Imported Upstream version 1.1.1d upstream/1.1.1d
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 18 Sep 2019 10:59:19 +0000 (12:59 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 18 Sep 2019 11:02:44 +0000 (13:02 +0200)
325 files changed:
CHANGES
Configurations/00-base-templates.conf
Configurations/10-main.conf
Configurations/15-ios.conf
Configurations/50-win-onecore.conf
Configurations/common0.tmpl
Configurations/unix-Makefile.tmpl
Configure
INSTALL
NEWS
NOTES.WIN
README
apps/apps.c
apps/apps.h
apps/ca.c
apps/dgst.c
apps/enc.c
apps/ocsp.c
apps/openssl.c
apps/pkcs12.c
apps/req.c
apps/s_apps.h
apps/s_cb.c
apps/s_client.c
apps/speed.c
apps/storeutl.c
config
crypto/aes/asm/aes-586.pl [deleted file]
crypto/aes/asm/aes-s390x.pl
crypto/aes/asm/aes-x86_64.pl [deleted file]
crypto/aes/asm/bsaes-x86_64.pl [deleted file]
crypto/asn1/a_time.c
crypto/asn1/a_type.c
crypto/asn1/x_bignum.c
crypto/bio/b_addr.c
crypto/bio/bss_dgram.c
crypto/bio/bss_file.c
crypto/bio/bss_mem.c
crypto/bn/asm/mips.pl
crypto/bn/bn_div.c
crypto/bn/bn_lcl.h
crypto/bn/bn_lib.c
crypto/bn/bn_prime.c
crypto/bn/bn_rand.c
crypto/bn/bn_sqrt.c
crypto/cms/cms_att.c
crypto/cms/cms_env.c
crypto/cms/cms_err.c
crypto/cms/cms_lcl.h
crypto/cms/cms_sd.c
crypto/cms/cms_smime.c
crypto/conf/conf_sap.c
crypto/ctype.c
crypto/dh/dh_check.c
crypto/dh/dh_gen.c
crypto/dh/dh_key.c
crypto/dh/dh_lib.c
crypto/dsa/dsa_ameth.c
crypto/dsa/dsa_err.c
crypto/dsa/dsa_ossl.c
crypto/dso/dso_dlfcn.c
crypto/ec/asm/ecp_nistz256-sparcv9.pl
crypto/ec/asm/ecp_nistz256-x86_64.pl
crypto/ec/asm/x25519-ppc64.pl
crypto/ec/ec_asn1.c
crypto/ec/ec_curve.c
crypto/ec/ec_lcl.h
crypto/ec/ec_lib.c
crypto/ec/ecdh_ossl.c
crypto/ec/ecdsa_ossl.c
crypto/ec/ecp_nistp224.c
crypto/ec/ecp_nistp256.c
crypto/ec/ecp_nistp521.c
crypto/ec/ecp_nistputil.c
crypto/ec/ecx_meth.c
crypto/engine/eng_devcrypto.c
crypto/engine/eng_openssl.c
crypto/err/err.c
crypto/err/openssl.txt
crypto/evp/bio_ok.c
crypto/evp/e_aes.c
crypto/evp/e_aria.c
crypto/evp/e_chacha20_poly1305.c
crypto/evp/e_rc5.c
crypto/evp/evp_err.c
crypto/evp/evp_lib.c
crypto/evp/m_sha3.c
crypto/include/internal/ctype.h
crypto/include/internal/rand_int.h
crypto/include/internal/sm2err.h
crypto/init.c
crypto/lhash/lhash.c
crypto/o_str.c
crypto/pem/pvkfmt.c
crypto/pkcs7/pk7_doit.c
crypto/rand/drbg_lib.c
crypto/rand/rand_err.c
crypto/rand/rand_lcl.h
crypto/rand/rand_lib.c
crypto/rand/rand_unix.c
crypto/rand/rand_win.c
crypto/rsa/rsa_ameth.c
crypto/rsa/rsa_err.c
crypto/rsa/rsa_gen.c
crypto/rsa/rsa_lib.c
crypto/rsa/rsa_ossl.c
crypto/s390xcap.c
crypto/sha/asm/keccak1600-armv4.pl
crypto/sha/asm/keccak1600-armv8.pl
crypto/sha/asm/sha512-sparcv9.pl
crypto/sm2/sm2_sign.c
crypto/store/loader_file.c
crypto/store/store_lib.c
crypto/threads_none.c
crypto/threads_pthread.c
crypto/threads_win.c
crypto/ui/ui_lib.c
crypto/ui/ui_openssl.c
crypto/uid.c
crypto/whrlpool/wp_block.c
crypto/x509/by_dir.c
crypto/x509/t_req.c
crypto/x509/x509_att.c
crypto/x509/x509_cmp.c
crypto/x509/x509_err.c
crypto/x509/x509_lu.c
crypto/x509/x509_vfy.c
crypto/x509v3/v3_alt.c
crypto/x509v3/v3_purp.c
demos/bio/descrip.mms
demos/evp/aesgcm.c
doc/HOWTO/proxy_certificates.txt
doc/man1/engine.pod
doc/man1/errstr.pod
doc/man1/pkcs12.pod
doc/man1/pkeyparam.pod
doc/man1/s_client.pod
doc/man1/s_server.pod
doc/man3/ADMISSIONS.pod
doc/man3/ASYNC_start_job.pod
doc/man3/BIO_connect.pod
doc/man3/BIO_f_ssl.pod
doc/man3/BIO_find_type.pod
doc/man3/BIO_new.pod
doc/man3/BIO_s_accept.pod
doc/man3/BIO_s_bio.pod
doc/man3/BIO_s_connect.pod
doc/man3/BIO_s_fd.pod
doc/man3/BIO_s_mem.pod
doc/man3/BIO_set_callback.pod
doc/man3/BN_generate_prime.pod
doc/man3/BN_mod_mul_montgomery.pod
doc/man3/BN_new.pod
doc/man3/CMS_final.pod
doc/man3/CRYPTO_THREAD_run_once.pod
doc/man3/CRYPTO_memcmp.pod [new file with mode: 0644]
doc/man3/DES_random_key.pod
doc/man3/DSA_generate_key.pod
doc/man3/DSA_sign.pod
doc/man3/ECDSA_SIG_new.pod
doc/man3/EVP_DigestInit.pod
doc/man3/EVP_DigestSignInit.pod
doc/man3/EVP_DigestVerifyInit.pod
doc/man3/EVP_PKEY_CTX_set_hkdf_md.pod
doc/man3/EVP_PKEY_CTX_set_tls1_prf_md.pod
doc/man3/EVP_PKEY_decrypt.pod
doc/man3/EVP_PKEY_derive.pod
doc/man3/EVP_PKEY_encrypt.pod
doc/man3/EVP_PKEY_sign.pod
doc/man3/EVP_PKEY_verify.pod
doc/man3/EVP_PKEY_verify_recover.pod
doc/man3/EVP_SealInit.pod
doc/man3/EVP_SignInit.pod
doc/man3/EVP_VerifyInit.pod
doc/man3/EVP_aria.pod
doc/man3/EVP_md5.pod
doc/man3/EVP_rc5_32_12_16_cbc.pod
doc/man3/OCSP_REQUEST_new.pod
doc/man3/OPENSSL_fork_prepare.pod
doc/man3/OSSL_STORE_LOADER.pod
doc/man3/OSSL_STORE_expect.pod
doc/man3/PKCS12_newpass.pod
doc/man3/RAND_DRBG_set_callbacks.pod
doc/man3/RAND_set_rand_method.pod
doc/man3/RSA_blinding_on.pod
doc/man3/RSA_generate_key.pod
doc/man3/RSA_padding_add_PKCS1_type_1.pod
doc/man3/RSA_public_encrypt.pod
doc/man3/RSA_sign_ASN1_OCTET_STRING.pod
doc/man3/SSL_CTX_config.pod
doc/man3/SSL_CTX_dane_enable.pod
doc/man3/SSL_CTX_get0_param.pod
doc/man3/SSL_CTX_new.pod
doc/man3/SSL_CTX_set_cipher_list.pod
doc/man3/SSL_CTX_set_generate_session_id.pod
doc/man3/SSL_CTX_set_session_id_context.pod
doc/man3/SSL_CTX_set_verify.pod
doc/man3/SSL_SESSION_get0_hostname.pod
doc/man3/SSL_get_error.pod
doc/man3/SSL_library_init.pod
doc/man3/SSL_set1_host.pod
doc/man3/SSL_write.pod
doc/man3/X509_STORE_CTX_get_error.pod
doc/man3/X509_STORE_CTX_set_verify_cb.pod
doc/man3/X509_STORE_add_cert.pod
doc/man3/X509_STORE_new.pod
doc/man3/X509_VERIFY_PARAM_set_flags.pod
doc/man3/X509_cmp.pod [new file with mode: 0644]
doc/man3/X509_get_extension_flags.pod
doc/man3/d2i_X509.pod
doc/man5/x509v3_config.pod
doc/man7/Ed25519.pod
doc/man7/RAND.pod
doc/man7/SM2.pod
doc/man7/X25519.pod
doc/man7/bio.pod
doc/man7/scrypt.pod
e_os.h
engines/build.info
engines/e_afalg.c
include/internal/constant_time_locl.h
include/internal/cryptlib.h
include/internal/dsoerr.h
include/internal/refcount.h
include/internal/thread_once.h
include/internal/tsan_assist.h
include/openssl/asn1err.h
include/openssl/asyncerr.h
include/openssl/bio.h
include/openssl/bioerr.h
include/openssl/bnerr.h
include/openssl/buffererr.h
include/openssl/cms.h
include/openssl/cmserr.h
include/openssl/comperr.h
include/openssl/conferr.h
include/openssl/cryptoerr.h
include/openssl/cterr.h
include/openssl/dherr.h
include/openssl/dsaerr.h
include/openssl/ec.h
include/openssl/ecerr.h
include/openssl/engineerr.h
include/openssl/evp.h
include/openssl/evperr.h
include/openssl/kdferr.h
include/openssl/objectserr.h
include/openssl/ocsperr.h
include/openssl/opensslv.h
include/openssl/pemerr.h
include/openssl/pkcs12err.h
include/openssl/pkcs7err.h
include/openssl/randerr.h
include/openssl/rsaerr.h
include/openssl/ssl.h
include/openssl/sslerr.h
include/openssl/store.h
include/openssl/storeerr.h
include/openssl/tls1.h
include/openssl/tserr.h
include/openssl/uierr.h
include/openssl/x509err.h
include/openssl/x509v3.h
include/openssl/x509v3err.h
ssl/d1_msg.c
ssl/record/rec_layer_s3.c
ssl/s3_lib.c
ssl/ssl_cert.c
ssl/ssl_ciph.c
ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/ssl_sess.c
ssl/statem/extensions.c
ssl/statem/extensions_clnt.c
ssl/statem/extensions_srvr.c
ssl/statem/statem_clnt.c
ssl/statem/statem_lib.c
ssl/statem/statem_srvr.c
ssl/t1_lib.c
ssl/tls13_enc.c
test/asn1_time_test.c
test/bio_memleak_test.c
test/bntest.c
test/build.info
test/certs/mkcert.sh
test/certs/server-pss-restrict-cert.pem [new file with mode: 0644]
test/certs/server-pss-restrict-key.pem [new file with mode: 0644]
test/certs/setup.sh
test/conf_include_test.c
test/ct_test.c
test/dhtest.c
test/drbgtest.c
test/dtlstest.c
test/ectest.c
test/enginetest.c
test/evp_extra_test.c
test/evp_test.c
test/recipes/30-test_evp_data/evpciph.txt
test/recipes/70-test_sslmessages.t
test/recipes/70-test_tls13kexmodes.t
test/recipes/70-test_tls13messages.t
test/recipes/80-test_cms.t
test/recipes/80-test_cms_data/bad_signtime_attr.cms [new file with mode: 0644]
test/recipes/80-test_cms_data/ct_multiple_attr.cms [new file with mode: 0644]
test/recipes/80-test_cms_data/no_ct_attr.cms [new file with mode: 0644]
test/recipes/80-test_cms_data/no_md_attr.cms [new file with mode: 0644]
test/recipes/90-test_sslapi.t
test/ssl-tests/20-cert-select.conf
test/ssl-tests/20-cert-select.conf.in
test/sslapitest.c
test/ssltestlib.c
test/ssltestlib.h
test/testutil.h
test/testutil/driver.c
test/testutil/random.c [new file with mode: 0644]
test/tls13secretstest.c
util/find-doc-nits
util/libcrypto.num
util/mkdef.pl
util/mkerr.pl
util/perl/OpenSSL/Test.pm
util/perl/TLSProxy/CertificateRequest.pm [new file with mode: 0644]
util/perl/TLSProxy/Message.pm
util/perl/TLSProxy/Proxy.pm
util/perl/checkhandshake.pm

diff --git a/CHANGES b/CHANGES
index c8662c3..c6ca343 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,101 @@
  https://github.com/openssl/openssl/commits/ and pick the appropriate
  release branch.
 
+ Changes between 1.1.1c and 1.1.1d [10 Sep 2019]
+
+  *) Fixed a fork protection issue. OpenSSL 1.1.1 introduced a rewritten random
+     number generator (RNG). This was intended to include protection in the
+     event of a fork() system call in order to ensure that the parent and child
+     processes did not share the same RNG state. However this protection was not
+     being used in the default case.
+
+     A partial mitigation for this issue is that the output from a high
+     precision timer is mixed into the RNG state so the likelihood of a parent
+     and child process sharing state is significantly reduced.
+
+     If an application already calls OPENSSL_init_crypto() explicitly using
+     OPENSSL_INIT_ATFORK then this problem does not occur at all.
+     (CVE-2019-1549)
+     [Matthias St. Pierre]
+
+  *) For built-in EC curves, ensure an EC_GROUP built from the curve name is
+     used even when parsing explicit parameters, when loading a serialized key
+     or calling `EC_GROUP_new_from_ecpkparameters()`/
+     `EC_GROUP_new_from_ecparameters()`.
+     This prevents bypass of security hardening and performance gains,
+     especially for curves with specialized EC_METHODs.
+     By default, if a key encoded with explicit parameters is loaded and later
+     serialized, the output is still encoded with explicit parameters, even if
+     internally a "named" EC_GROUP is used for computation.
+     [Nicola Tuveri]
+
+  *) Compute ECC cofactors if not provided during EC_GROUP construction. Before
+     this change, EC_GROUP_set_generator would accept order and/or cofactor as
+     NULL. After this change, only the cofactor parameter can be NULL. It also
+     does some minimal sanity checks on the passed order.
+     (CVE-2019-1547)
+     [Billy Bob Brumley]
+
+  *) Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey.
+     An attack is simple, if the first CMS_recipientInfo is valid but the
+     second CMS_recipientInfo is chosen ciphertext. If the second
+     recipientInfo decodes to PKCS #1 v1.5 form plaintext, the correct
+     encryption key will be replaced by garbage, and the message cannot be
+     decoded, but if the RSA decryption fails, the correct encryption key is
+     used and the recipient will not notice the attack.
+     As a work around for this potential attack the length of the decrypted
+     key must be equal to the cipher default key length, in case the
+     certifiate is not given and all recipientInfo are tried out.
+     The old behaviour can be re-enabled in the CMS code by setting the
+     CMS_DEBUG_DECRYPT flag.
+     (CVE-2019-1563)
+     [Bernd Edlinger]
+
+  *) Early start up entropy quality from the DEVRANDOM seed source has been
+     improved for older Linux systems.  The RAND subsystem will wait for
+     /dev/random to be producing output before seeding from /dev/urandom.
+     The seeded state is stored for future library initialisations using
+     a system global shared memory segment.  The shared memory identifier
+     can be configured by defining OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID to
+     the desired value.  The default identifier is 114.
+     [Paul Dale]
+
+  *) Correct the extended master secret constant on EBCDIC systems. Without this
+     fix TLS connections between an EBCDIC system and a non-EBCDIC system that
+     negotiate EMS will fail. Unfortunately this also means that TLS connections
+     between EBCDIC systems with this fix, and EBCDIC systems without this
+     fix will fail if they negotiate EMS.
+     [Matt Caswell]
+
+  *) Use Windows installation paths in the mingw builds
+
+     Mingw isn't a POSIX environment per se, which means that Windows
+     paths should be used for installation.
+     (CVE-2019-1552)
+     [Richard Levitte]
+
+  *) Changed DH_check to accept parameters with order q and 2q subgroups.
+     With order 2q subgroups the bit 0 of the private key is not secret
+     but DH_generate_key works around that by clearing bit 0 of the
+     private key for those. This avoids leaking bit 0 of the private key.
+     [Bernd Edlinger]
+
+  *) Significantly reduce secure memory usage by the randomness pools.
+     [Paul Dale]
+
+  *) Revert the DEVRANDOM_WAIT feature for Linux systems
+
+     The DEVRANDOM_WAIT feature added a select() call to wait for the
+     /dev/random device to become readable before reading from the
+     /dev/urandom device.
+
+     It turned out that this change had negative side effects on
+     performance which were not acceptable. After some discussion it
+     was decided to revert this feature and leave it up to the OS
+     resp. the platform maintainer to ensure a proper initialization
+     during early boot time.
+     [Matthias St. Pierre]
+
  Changes between 1.1.1b and 1.1.1c [28 May 2019]
 
   *) Add build tests for C++.  These are generated files that only do one
      (CVE-2019-1543)
      [Matt Caswell]
 
+  *) Add DEVRANDOM_WAIT feature for Linux systems
+
+     On older Linux systems where the getrandom() system call is not available,
+     OpenSSL normally uses the /dev/urandom device for seeding its CSPRNG.
+     Contrary to getrandom(), the /dev/urandom device will not block during
+     early boot when the kernel CSPRNG has not been seeded yet.
+
+     To mitigate this known weakness, use select() to wait for /dev/random to
+     become readable before reading from /dev/urandom.
+
   *) Ensure that SM2 only uses SM3 as digest algorithm
      [Paul Yang]
 
         SSL_set_ciphersuites()
      [Matt Caswell]
 
-  *) Memory allocation failures consistenly add an error to the error
+  *) Memory allocation failures consistently add an error to the error
      stack.
      [Rich Salz]
 
      reason texts, thereby removing some of the footprint that may not
      be interesting if those errors aren't displayed anyway.
 
-     NOTE: it's still possible for any application or module to have it's
+     NOTE: it's still possible for any application or module to have its
      own set of error texts inserted.  The routines are there, just not
      used by default when no-err is given.
      [Richard Levitte]
@@ -8826,7 +8931,7 @@ des-cbc           3624.96k     5258.21k     5530.91k     5624.30k     5628.26k
  Changes between 0.9.6g and 0.9.6h  [5 Dec 2002]
 
   *) New function OPENSSL_cleanse(), which is used to cleanse a section of
-     memory from it's contents.  This is done with a counter that will
+     memory from its contents.  This is done with a counter that will
      place alternating values in each byte.  This can be used to solve
      two issues: 1) the removal of calls to memset() by highly optimizing
      compilers, and 2) cleansing with other values than 0, since those can
index 5fd995c..e01dc63 100644 (file)
@@ -198,7 +198,7 @@ my %targets=(
        bn_asm_src      => "bn-586.s co-586.s x86-mont.s x86-gf2m.s",
        ec_asm_src      => "ecp_nistz256.c ecp_nistz256-x86.s",
        des_asm_src     => "des-586.s crypt586.s",
-       aes_asm_src     => "aes-586.s vpaes-x86.s aesni-x86.s",
+       aes_asm_src     => "aes_core.c aes_cbc.c vpaes-x86.s aesni-x86.s",
        bf_asm_src      => "bf-586.s",
        md5_asm_src     => "md5-586.s",
        cast_asm_src    => "cast-586.s",
@@ -223,7 +223,7 @@ my %targets=(
        cpuid_asm_src   => "x86_64cpuid.s",
        bn_asm_src      => "asm/x86_64-gcc.c x86_64-mont.s x86_64-mont5.s x86_64-gf2m.s rsaz_exp.c rsaz-x86_64.s rsaz-avx2.s",
        ec_asm_src      => "ecp_nistz256.c ecp_nistz256-x86_64.s x25519-x86_64.s",
-       aes_asm_src     => "aes-x86_64.s vpaes-x86_64.s bsaes-x86_64.s aesni-x86_64.s aesni-sha1-x86_64.s aesni-sha256-x86_64.s aesni-mb-x86_64.s",
+       aes_asm_src     => "aes_core.c aes_cbc.c vpaes-x86_64.s aesni-x86_64.s aesni-sha1-x86_64.s aesni-sha256-x86_64.s aesni-mb-x86_64.s",
        md5_asm_src     => "md5-x86_64.s",
        sha1_asm_src    => "sha1-x86_64.s sha256-x86_64.s sha512-x86_64.s sha1-mb-x86_64.s sha256-mb-x86_64.s",
        rc4_asm_src     => "rc4-x86_64.s rc4-md5-x86_64.s",
index 930f2d3..3c4299d 100644 (file)
@@ -1111,7 +1111,7 @@ my %targets = (
         thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "self",
-        module_ldflags   => "-Wl,-G,-bsymbolic,-bexpall",
+        module_ldflags   => "-Wl,-G,-bsymbolic,-bnoentry",
         shared_ldflag    => "-Wl,-G,-bsymbolic,-bnoentry",
         shared_defflag   => "-Wl,-bE:",
         shared_extension => ".so.\$(SHLIB_VERSION_NUMBER)",
@@ -1397,6 +1397,10 @@ my %targets = (
         shared_extension => ".dll",
         multilib         => "",
         apps_aux_src     => add("win32_init.c"),
+        # "WOW" stands for "Windows on Windows", and that word engages
+        # some installation path heuristics in unix-Makefile.tmpl...
+        build_scheme     => add("WOW", { separator => undef }),
+
     },
     "mingw64" => {
         # As for OPENSSL_USE_APPLINK. Applink makes it possible to use
index 1bb9f48..f404077 100644 (file)
@@ -1,6 +1,6 @@
 #### iPhoneOS/iOS
 #
-# It takes recent enough XCode to use following two targets. It shouldn't
+# It takes recent enough Xcode to use following two targets. It shouldn't
 # be a problem by now, but if they don't work, original targets below
 # that depend on manual definition of environment variables should still
 # work...
index 51cb381..d478f42 100644 (file)
@@ -1,6 +1,6 @@
 # Windows OneCore targets.
 #
-# OneCore is new API stability "contract" that transends Desktop, IoT and
+# OneCore is new API stability "contract" that transcends Desktop, IoT and
 # Mobile[?] Windows editions. It's a set up "umbrella" libraries that
 # export subset of Win32 API that are common to all Windows 10 devices.
 #
index 03acb3e..852b1fb 100644 (file)
@@ -22,7 +22,7 @@
  our @generated =
      sort ( ( grep { defined $unified_info{generate}->{$_} }
               sort keys %generatables ),
-            # Scripts are assumed to be generated, so add thhem too
+            # Scripts are assumed to be generated, so add them too
             ( grep { defined $unified_info{sources}->{$_} }
               @{$unified_info{scripts}} ) );
 
index 1292053..7db7578 100644 (file)
      our $dsoext = $target{dso_extension} || ".so";
      our $makedepprog = $disabled{makedepend} ? undef : $config{makedepprog};
 
+     # $mingw_installroot and $mingw_commonroot is relevant for mingw only.
+     my $build_scheme = $target{build_scheme};
+     my $install_flavour = $build_scheme->[$#$build_scheme]; # last element
+     my $mingw_installenv = $install_flavour eq "WOW" ? "ProgramFiles(x86)"
+                                                      : "ProgramW6432";
+     my $mingw_commonenv = $install_flavour eq "WOW" ? "CommonProgramFiles(x86)"
+                                                     : "CommonProgramW6432";
+     our $mingw_installroot =
+         defined($ENV{$mingw_installenv}) ? $mingw_installenv : 'ProgramFiles';
+     our $mingw_commonroot =
+         defined($ENV{$mingw_commonenv}) ? $mingw_commonenv : 'CommonProgramFiles';
+     my $mingw_installdflt =
+         $install_flavour eq "WOW" ? "C:/Program Files (x86)"
+                                   : "C:/Program Files";
+     my $mingw_commondflt = "$mingw_installdflt/Common Files";
+
+     # expand variables early
+     $mingw_installroot = $ENV{$mingw_installroot} // $mingw_installdflt;
+     $mingw_commonroot = $ENV{$mingw_commonroot} // $mingw_commondflt;
+
      sub windowsdll { $config{target} =~ /^(?:Cygwin|mingw)/ }
 
      # Shared AIX support is special. We put libcrypto[64].so.ver into
@@ -132,6 +152,7 @@ APPS_OPENSSL={- use File::Spec::Functions;
 # Normally it is left empty.
 DESTDIR=
 
+{- output_off() if $config{target} =~ /^mingw/; "" -}
 # Do not edit these manually. Use Configure with --prefix or --openssldir
 # to change this!  Short explanation in the top comment in Configure
 INSTALLTOP={- # $prefix is used in the OPENSSLDIR perl snippet
@@ -175,6 +196,83 @@ ENGINESDIR=$(libdir)/engines-{- $sover_dirname -}
 # Convenience variable for those who want to set the rpath in shared
 # libraries and applications
 LIBRPATH=$(libdir)
+{- output_on() if $config{target} =~ /^mingw/;
+   output_off() if $config{target} !~ /^mingw/;
+   "" -}
+# Do not edit these manually. Use Configure with --prefix or --openssldir
+# to change this!  Short explanation in the top comment in Configure
+INSTALLTOP_dev={- # $prefix is used in the OPENSSLDIR perl snippet
+                  #
+                  use File::Spec::Win32;
+                  my $prefix_default = "$mingw_installroot/OpenSSL";
+                  our $prefix =
+                      File::Spec::Win32->canonpath($config{prefix}
+                                                  || $prefix_default);
+                  our ($prefix_dev, $prefix_dir, $prefix_file) =
+                      File::Spec::Win32->splitpath($prefix, 1);
+                  $prefix =~ s|\\|/|g;
+                  $prefix_dir =~ s|\\|/|g;
+                  $prefix_dev -}
+INSTALLTOP_dir={- my $x = File::Spec::Win32->canonpath($prefix_dir);
+                  $x =~ s|\\|/|g;
+                  $x -}
+OPENSSLDIR_dev={- #
+                  # The logic here is that if no --openssldir was given,
+                  # OPENSSLDIR will get the value "$mingw_commonroot/SSL".
+                  # If --openssldir was given and the value is an absolute
+                  # path, OPENSSLDIR will get its value without change.
+                  # If the value from --openssldir is a relative path,
+                  # OPENSSLDIR will get $prefix with the --openssldir
+                  # value appended as a subdirectory.
+                  #
+                  use File::Spec::Win32;
+                  our $openssldir =
+                      $config{openssldir} ?
+                          (File::Spec::Win32->file_name_is_absolute($config{openssldir}) ?
+                               File::Spec::Win32->canonpath($config{openssldir})
+                               : File::Spec::Win32->catdir($prefix, $config{openssldir}))
+                          : File::Spec::Win32->canonpath("$mingw_commonroot/SSL");
+                  our ($openssldir_dev, $openssldir_dir, $openssldir_file) =
+                      File::Spec::Win32->splitpath($openssldir, 1);
+                  $openssldir =~ s|\\|/|g;
+                  $openssldir_dir =~ s|\\|/|g;
+                  $openssldir_dev -}
+OPENSSLDIR_dir={- my $x = File::Spec::Win32->canonpath($openssldir_dir);
+                  $x =~ s|\\|/|g;
+                  $x -}
+LIBDIR={- our $libdir = $config{libdir} || "lib";
+          File::Spec::Win32->file_name_is_absolute($libdir) ? "" : $libdir -}
+ENGINESDIR_dev={- use File::Spec::Win32;
+                  our $enginesdir =
+                      File::Spec::Win32->catdir($prefix,$libdir,
+                                                "engines-$sover_dirname");
+                  our ($enginesdir_dev, $enginesdir_dir, $enginesdir_file) =
+                      File::Spec::Win32->splitpath($enginesdir, 1);
+                  $enginesdir =~ s|\\|/|g;
+                  $enginesdir_dir =~ s|\\|/|g;
+                  $enginesdir_dev -}
+ENGINESDIR_dir={- my $x = File::Spec::Win32->canonpath($enginesdir_dir);
+                  $x =~ s|\\|/|g;
+                  $x -}
+# In a Windows environment, $(DESTDIR) is harder to contatenate with other
+# directory variables, because both may contain devices.  What we do here is
+# to adapt INSTALLTOP, OPENSSLDIR and ENGINESDIR depending on if $(DESTDIR)
+# has a value or not, to ensure that concatenation will always work further
+# down.
+ifneq "$(DESTDIR)" ""
+INSTALLTOP=$(INSTALLTOP_dir)
+OPENSSLDIR=$(OPENSSLDIR_dir)
+ENGINESDIR=$(ENGINESDIR_dir)
+else
+INSTALLTOP=$(INSTALLTOP_dev)$(INSTALLTOP_dir)
+OPENSSLDIR=$(OPENSSLDIR_dev)$(OPENSSLDIR_dir)
+ENGINESDIR=$(ENGINESDIR_dev)$(ENGINESDIR_dir)
+endif
+
+# $(libdir) is chosen to be compatible with the GNU coding standards
+libdir={- File::Spec::Win32->file_name_is_absolute($libdir)
+          ? $libdir : '$(INSTALLTOP)/$(LIBDIR)' -}
+{- output_on() if $config{target} !~ /^mingw/; "" -}
 
 MANDIR=$(INSTALLTOP)/share/man
 DOCDIR=$(INSTALLTOP)/share/doc/$(BASENAME)
@@ -418,13 +516,13 @@ libclean:
 clean: libclean
        $(RM) $(PROGRAMS) $(TESTPROGS) $(ENGINES) $(SCRIPTS)
        $(RM) $(GENERATED_MANDATORY) $(GENERATED)
-       -$(RM) `find . -name .git -prune -o -name '*{- $depext -}' -print`
-       -$(RM) `find . -name .git -prune -o -name '*{- $objext -}' -print`
+       -$(RM) `find . -name '*{- $depext -}' \! -name '.*' -print`
+       -$(RM) `find . -name '*{- $objext -}' \! -name '.*' -print`
        $(RM) core
        $(RM) tags TAGS doc-nits
        $(RM) -r test/test-runs
        $(RM) openssl.pc libcrypto.pc libssl.pc
-       -$(RM) `find . -name .git -prune -o -type l -print`
+       -$(RM) `find . -type l \! -name '.*' -print`
        $(RM) $(TARFILE)
 
 distclean: clean
@@ -449,7 +547,7 @@ uninstall_sw: uninstall_runtime uninstall_engines uninstall_dev
 install_docs: install_man_docs install_html_docs
 
 uninstall_docs: uninstall_man_docs uninstall_html_docs
-       $(RM) -r -v $(DESTDIR)$(DOCDIR)
+       $(RM) -r $(DESTDIR)$(DOCDIR)
 
 install_ssldirs:
        @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(OPENSSLDIR)/certs
index 254b04c..5a69983 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -87,9 +87,6 @@ my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lx
 #               linked openssl executable has rather debugging value than
 #               production quality.
 #
-# DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
-#               provided to stack calls. Generates unique stack functions for
-#               each possible stack type.
 # BN_LLONG      use the type 'long long' in crypto/bn/bn.h
 # RC4_CHAR      use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
 # Following are set automatically by this script
@@ -145,13 +142,13 @@ my @gcc_devteam_warn = qw(
 #       -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
 #       -Wextended-offsetof -- no, needed in CMS ASN1 code
 my @clang_devteam_warn = qw(
+    -Wno-unknown-warning-option
     -Wswitch-default
     -Wno-parentheses-equality
     -Wno-language-extension-token
     -Wno-extended-offsetof
     -Wconditional-uninitialized
     -Wincompatible-pointer-types-discards-qualifiers
-    -Wno-unknown-warning-option
     -Wmissing-variable-declarations
 );
 
diff --git a/INSTALL b/INSTALL
index 0b6a3fd..2119cba 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -98,6 +98,9 @@
     $ nmake test
     $ nmake install
 
+ Note that in order to perform the install step above you need to have
+ appropriate permissions to write to the installation directory.
+
  If any of these steps fails, see section Installation in Detail below.
 
  This will build and install OpenSSL in the default location, which is:
            OpenSSL version number with underscores instead of periods.
   Windows: C:\Program Files\OpenSSL or C:\Program Files (x86)\OpenSSL
 
+ The installation directory should be appropriately protected to ensure
+ unprivileged users cannot make changes to OpenSSL binaries or files, or install
+ engines. If you already have a pre-installed version of OpenSSL as part of
+ your Operating System it is recommended that you do not overwrite the system
+ version and instead install to somewhere else.
+
  If you want to install it anywhere else, run config like this:
 
   On Unix:
                    Don't build with support for deprecated APIs below the
                    specified version number. For example "--api=1.1.0" will
                    remove support for all APIS that were deprecated in OpenSSL
-                   version 1.1.0 or below.
+                   version 1.1.0 or below. This is a rather specialized option
+                   for developers. If you just intend to remove all deprecated
+                   APIs entirely (up to the current version), it is easier
+                   to add the 'no-deprecated' option instead (see below).
 
   --cross-compile-prefix=PREFIX
                    The PREFIX to include in front of commands for your
                                source exists.
                    getrandom:  Use the L<getrandom(2)> or equivalent system
                                call.
-                   devrandom:  Use the the first device from the DEVRANDOM list
+                   devrandom:  Use the first device from the DEVRANDOM list
                                which can be opened to read random bytes. The
                                DEVRANDOM preprocessor constant expands to
                                "/dev/urandom","/dev/random","/dev/srandom" on
        $ mms install                                    ! OpenVMS
        $ nmake install                                  # Windows
 
-     This will install all the software components in this directory
-     tree under PREFIX (the directory given with --prefix or its
+     Note that in order to perform the install step above you need to have
+     appropriate permissions to write to the installation directory.
+
+     The above commands will install all the software components in this
+     directory tree under PREFIX (the directory given with --prefix or its
      default):
 
        Unix:
                         for private key files.
          misc           Various scripts.
 
+     The installation directory should be appropriately protected to ensure
+     unprivileged users cannot make changes to OpenSSL binaries or files, or
+     install engines. If you already have a pre-installed version of OpenSSL as
+     part of your Operating System it is recommended that you do not overwrite
+     the system version and instead install to somewhere else.
+
      Package builders who want to configure the library for standard
      locations, but have the package installed somewhere else so that
      it can easily be packaged, can use
diff --git a/NEWS b/NEWS
index 0e38f69..1c88dee 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,23 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
+  Major changes between OpenSSL 1.1.1c and OpenSSL 1.1.1d [10 Sep 2019]
+
+      o Fixed a fork protection issue (CVE-2019-1549)
+      o Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey
+        (CVE-2019-1563)
+      o For built-in EC curves, ensure an EC_GROUP built from the curve name is
+        used even when parsing explicit parameters
+      o Compute ECC cofactors if not provided during EC_GROUP construction
+        (CVE-2019-1547)
+      o Early start up entropy quality from the DEVRANDOM seed source has been
+        improved for older Linux systems
+      o Correct the extended master secret constant on EBCDIC systems
+      o Use Windows installation paths in the mingw builds (CVE-2019-1552)
+      o Changed DH_check to accept parameters with order q and 2q subgroups
+      o Significantly reduce secure memory usage by the randomness pools
+      o Revert the DEVRANDOM_WAIT feature for Linux systems
+
   Major changes between OpenSSL 1.1.1b and OpenSSL 1.1.1c [28 May 2019]
 
       o Prevent over long nonces in ChaCha20-Poly1305 (CVE-2019-1543)
 
   Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i [14 Oct 2005]:
 
-      o Give EVP_MAX_MD_SIZE it's old value, except for a FIPS build.
+      o Give EVP_MAX_MD_SIZE its old value, except for a FIPS build.
 
   Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.7h [11 Oct 2005]:
 
index 4d39d06..b1cb542 100644 (file)
--- a/NOTES.WIN
+++ b/NOTES.WIN
    This naturally implies that you've installed corresponding add-on
    packages.
 
+ Independently of the method chosen to build for mingw, the installation
+ paths are similar to those used when building with VC-* targets, except
+ that in case the fallbacks mentioned there aren't possible (typically
+ when cross compiling on Linux), the paths will be the following:
+
+ For mingw:
+
+     PREFIX:      C:/Program Files (x86)/OpenSSL
+     OPENSSLDIR   C:/Program Files (x86)/Common Files/SSL
+
+ For mingw64:
+
+     PREFIX:      C:/Program Files/OpenSSL
+     OPENSSLDIR   C:/Program Files/Common Files/SSL
+
  Linking your application
  ========================
 
diff --git a/README b/README
index 2975715..51bb478 100644 (file)
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
 
- OpenSSL 1.1.1c 28 May 2019
+ OpenSSL 1.1.1d 10 Sep 2019
 
  Copyright (c) 1998-2019 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
index 36cb0b2..7177c5d 100644 (file)
@@ -40,7 +40,6 @@
 #endif
 #include <openssl/bn.h>
 #include <openssl/ssl.h>
-#include "s_apps.h"
 #include "apps.h"
 
 #ifdef _WIN32
@@ -48,6 +47,14 @@ static int WIN32_rename(const char *from, const char *to);
 # define rename(from,to) WIN32_rename((from),(to))
 #endif
 
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+# include <conio.h>
+#endif
+
+#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
+# define _kbhit kbhit
+#endif
+
 typedef struct {
     const char *name;
     unsigned long flag;
index d9eb650..4a3e1a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -444,11 +444,9 @@ void destroy_ui_method(void);
 const UI_METHOD *get_ui_method(void);
 
 int chopup_args(ARGS *arg, char *buf);
-# ifdef HEADER_X509_H
 int dump_cert_text(BIO *out, X509 *x);
 void print_name(BIO *out, const char *title, X509_NAME *nm,
                 unsigned long lflags);
-# endif
 void print_bignum_var(BIO *, const BIGNUM *, const char*,
                       int, unsigned char *);
 void print_array(BIO *, const char *, int, const unsigned char *);
index 69207c0..a4a7712 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -722,7 +722,7 @@ end_of_options:
 
     /*****************************************************************/
     if (req || gencrl) {
-        if (spkac_file != NULL) {
+        if (spkac_file != NULL && outfile != NULL) {
             output_der = 1;
             batch = 1;
         }
index d158a0c..d6f5a0e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -421,7 +421,7 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
     size_t len;
     int i;
 
-    for (;;) {
+    while (BIO_pending(bp) || !BIO_eof(bp)) {
         i = BIO_read(bp, (char *)buf, BUFSIZE);
         if (i < 0) {
             BIO_printf(bio_err, "Read Error in %s\n", file);
index de33e57..d1772f3 100644 (file)
@@ -586,7 +586,7 @@ int enc_main(int argc, char **argv)
     if (benc != NULL)
         wbio = BIO_push(benc, wbio);
 
-    for (;;) {
+    while (BIO_pending(rbio) || !BIO_eof(rbio)) {
         inl = BIO_read(rbio, (char *)buff, bsize);
         if (inl <= 0)
             break;
index 066a2e4..5d23918 100644 (file)
@@ -1416,9 +1416,11 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
         *q = '\0';
 
         /*
-         * Skip "GET / HTTP..." requests often used by load-balancers
+         * Skip "GET / HTTP..." requests often used by load-balancers.  Note:
+         * 'p' was incremented above to point to the first byte *after* the
+         * leading slash, so with 'GET / ' it is now an empty string.
          */
-        if (p[1] == '\0')
+        if (p[0] == '\0')
             goto out;
 
         len = urldecode(p);
index a872e2c..9648f35 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -22,7 +22,6 @@
 # include <openssl/engine.h>
 #endif
 #include <openssl/err.h>
-#include "s_apps.h"
 /* Needed to get the other O_xxx flags. */
 #ifdef OPENSSL_SYS_VMS
 # include <unixio.h>
index 719a309..d0600b3 100644 (file)
@@ -838,7 +838,7 @@ static int alg_print(const X509_ALGOR *alg)
                 goto done;
             }
             BIO_printf(bio_err, ", Salt length: %d, Cost(N): %ld, "
-                       "Block size(r): %ld, Paralelizm(p): %ld",
+                       "Block size(r): %ld, Parallelism(p): %ld",
                        ASN1_STRING_length(kdf->salt),
                        ASN1_INTEGER_get(kdf->costParameter),
                        ASN1_INTEGER_get(kdf->blockSize),
index 6fd28a2..f9d6fba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -881,9 +881,19 @@ int req_main(int argc, char **argv)
 
     if (text) {
         if (x509)
-            X509_print_ex(out, x509ss, get_nameopt(), reqflag);
+            ret = X509_print_ex(out, x509ss, get_nameopt(), reqflag);
         else
-            X509_REQ_print_ex(out, req, get_nameopt(), reqflag);
+            ret = X509_REQ_print_ex(out, req, get_nameopt(), reqflag);
+
+        if (ret == 0) {
+            if (x509)
+              BIO_printf(bio_err, "Error printing certificate\n");
+            else
+              BIO_printf(bio_err, "Error printing certificate request\n");
+
+            ERR_print_errors(bio_err);
+            goto end;
+        }
     }
 
     if (subject) {
index 0a3bc96..f94e659 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -9,13 +9,7 @@
 
 #include <openssl/opensslconf.h>
 
-#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
-# include <conio.h>
-#endif
-
-#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
-# define _kbhit kbhit
-#endif
+#include <openssl/ssl.h>
 
 #define PORT            "4433"
 #define PROTOCOL        "tcp"
@@ -24,17 +18,15 @@ typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context);
 int do_server(int *accept_sock, const char *host, const char *port,
               int family, int type, int protocol, do_server_cb cb,
               unsigned char *context, int naccept, BIO *bio_s_out);
-#ifdef HEADER_X509_H
+
 int verify_callback(int ok, X509_STORE_CTX *ctx);
-#endif
-#ifdef HEADER_SSL_H
+
 int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
 int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
                        STACK_OF(X509) *chain, int build_chain);
 int ssl_print_sigalgs(BIO *out, SSL *s);
 int ssl_print_point_formats(BIO *out, SSL *s);
 int ssl_print_groups(BIO *out, SSL *s, int noshared);
-#endif
 int ssl_print_tmp_key(BIO *out, SSL *s);
 int init_client(int *sock, const char *host, const char *port,
                 const char *bindhost, const char *bindport,
@@ -44,13 +36,11 @@ int should_retry(int i);
 long bio_dump_callback(BIO *bio, int cmd, const char *argp,
                        int argi, long argl, long ret);
 
-#ifdef HEADER_SSL_H
 void apps_ssl_info_callback(const SSL *s, int where, int ret);
 void msg_cb(int write_p, int version, int content_type, const void *buf,
             size_t len, SSL *ssl, void *arg);
 void tlsext_cb(SSL *s, int client_server, int type, const unsigned char *data,
                int len, void *arg);
-#endif
 
 int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
                              unsigned int *cookie_len);
@@ -75,7 +65,6 @@ int args_excert(int option, SSL_EXCERT **pexc);
 int load_excert(SSL_EXCERT **pexc);
 void print_verify_detail(SSL *s, BIO *bio);
 void print_ssl_summary(SSL *s);
-#ifdef HEADER_SSL_H
 int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, SSL_CTX *ctx);
 int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls,
                      int crl_download);
@@ -86,4 +75,3 @@ int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath,
 void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose);
 int set_keylog_file(SSL_CTX *ctx, const char *keylog_file);
 void print_ca_names(BIO *bio, SSL *s);
-#endif
index 520323c..5dc1d03 100644 (file)
@@ -1525,7 +1525,8 @@ void print_ca_names(BIO *bio, SSL *s)
     int i;
 
     if (sk == NULL || sk_X509_NAME_num(sk) == 0) {
-        BIO_printf(bio, "---\nNo %s certificate CA names sent\n", cs);
+        if (!SSL_is_server(s))
+            BIO_printf(bio, "---\nNo %s certificate CA names sent\n", cs);
         return;
     }
 
index b85339a..26a6789 100644 (file)
@@ -2345,7 +2345,7 @@ int s_client_main(int argc, char **argv)
             (void)BIO_flush(fbio);
             /*
              * The first line is the HTTP response.  According to RFC 7230,
-             * it's formated exactly like this:
+             * it's formatted exactly like this:
              *
              * HTTP/d.d ddd Reason text\r\n
              */
index 8d4b169..2014950 100644 (file)
@@ -1790,7 +1790,7 @@ int speed_main(int argc, char **argv)
         }
 
         buflen = lengths[size_num - 1];
-        if (buflen < 36)    /* size of random vector in RSA bencmark */
+        if (buflen < 36)    /* size of random vector in RSA benchmark */
             buflen = 36;
         buflen += MAX_MISALIGNMENT + 1;
         loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
index 50007f6..644fe28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -125,7 +125,7 @@ int storeutl_main(int argc, char *argv[])
                 }
                 /*
                  * If expected wasn't set at this point, it means the map
-                 * isn't syncronised with the possible options leading here.
+                 * isn't synchronised with the possible options leading here.
                  */
                 OPENSSL_assert(expected != 0);
             }
diff --git a/config b/config
index d0e31b6..c1a94d4 100755 (executable)
--- a/config
+++ b/config
@@ -498,12 +498,12 @@ case "$GUESSOS" in
            OUT="darwin64-x86_64-cc"
        fi ;;
   armv6+7-*-iphoneos)
-       __CNF_CFLAGS="$__CNF_CFLAGS -arch%20armv6 -arch%20armv7"
-       __CNF_CXXFLAGS="$__CNF_CXXFLAGS -arch%20armv6 -arch%20armv7"
+       __CNF_CFLAGS="$__CNF_CFLAGS -arch armv6 -arch armv7"
+       __CNF_CXXFLAGS="$__CNF_CXXFLAGS -arch armv6 -arch armv7"
        OUT="iphoneos-cross" ;;
   *-*-iphoneos)
-       __CNF_CFLAGS="$__CNF_CFLAGS -arch%20${MACHINE}"
-       __CNF_CXXFLAGS="$__CNF_CXXFLAGS -arch%20${MACHINE}"
+       __CNF_CFLAGS="$__CNF_CFLAGS -arch ${MACHINE}"
+       __CNF_CXXFLAGS="$__CNF_CXXFLAGS -arch ${MACHINE}"
        OUT="iphoneos-cross" ;;
   arm64-*-iphoneos|*-*-ios64)
        OUT="ios64-cross" ;;
diff --git a/crypto/aes/asm/aes-586.pl b/crypto/aes/asm/aes-586.pl
deleted file mode 100755 (executable)
index 29059ed..0000000
+++ /dev/null
@@ -1,3000 +0,0 @@
-#! /usr/bin/env perl
-# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-#
-# Licensed under the OpenSSL license (the "License").  You may not use
-# this file except in compliance with the License.  You can obtain a copy
-# in the file LICENSE in the source distribution or at
-# https://www.openssl.org/source/license.html
-
-#
-# ====================================================================
-# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-#
-# Version 4.3.
-#
-# You might fail to appreciate this module performance from the first
-# try. If compared to "vanilla" linux-ia32-icc target, i.e. considered
-# to be *the* best Intel C compiler without -KPIC, performance appears
-# to be virtually identical... But try to re-configure with shared
-# library support... Aha! Intel compiler "suddenly" lags behind by 30%
-# [on P4, more on others]:-) And if compared to position-independent
-# code generated by GNU C, this code performs *more* than *twice* as
-# fast! Yes, all this buzz about PIC means that unlike other hand-
-# coded implementations, this one was explicitly designed to be safe
-# to use even in shared library context... This also means that this
-# code isn't necessarily absolutely fastest "ever," because in order
-# to achieve position independence an extra register has to be
-# off-loaded to stack, which affects the benchmark result.
-#
-# Special note about instruction choice. Do you recall RC4_INT code
-# performing poorly on P4? It might be the time to figure out why.
-# RC4_INT code implies effective address calculations in base+offset*4
-# form. Trouble is that it seems that offset scaling turned to be
-# critical path... At least eliminating scaling resulted in 2.8x RC4
-# performance improvement [as you might recall]. As AES code is hungry
-# for scaling too, I [try to] avoid the latter by favoring off-by-2
-# shifts and masking the result with 0xFF<<2 instead of "boring" 0xFF.
-#
-# As was shown by Dean Gaudet, the above note turned out to be
-# void. Performance improvement with off-by-2 shifts was observed on
-# intermediate implementation, which was spilling yet another register
-# to stack... Final offset*4 code below runs just a tad faster on P4,
-# but exhibits up to 10% improvement on other cores.
-#
-# Second version is "monolithic" replacement for aes_core.c, which in
-# addition to AES_[de|en]crypt implements AES_set_[de|en]cryption_key.
-# This made it possible to implement little-endian variant of the
-# algorithm without modifying the base C code. Motivating factor for
-# the undertaken effort was that it appeared that in tight IA-32
-# register window little-endian flavor could achieve slightly higher
-# Instruction Level Parallelism, and it indeed resulted in up to 15%
-# better performance on most recent Âµ-archs...
-#
-# Third version adds AES_cbc_encrypt implementation, which resulted in
-# up to 40% performance improvement of CBC benchmark results. 40% was
-# observed on P4 core, where "overall" improvement coefficient, i.e. if
-# compared to PIC generated by GCC and in CBC mode, was observed to be
-# as large as 4x:-) CBC performance is virtually identical to ECB now
-# and on some platforms even better, e.g. 17.6 "small" cycles/byte on
-# Opteron, because certain function prologues and epilogues are
-# effectively taken out of the loop...
-#
-# Version 3.2 implements compressed tables and prefetch of these tables
-# in CBC[!] mode. Former means that 3/4 of table references are now
-# misaligned, which unfortunately has negative impact on elder IA-32
-# implementations, Pentium suffered 30% penalty, PIII - 10%.
-#
-# Version 3.3 avoids L1 cache aliasing between stack frame and
-# S-boxes, and 3.4 - L1 cache aliasing even between key schedule. The
-# latter is achieved by copying the key schedule to controlled place in
-# stack. This unfortunately has rather strong impact on small block CBC
-# performance, ~2x deterioration on 16-byte block if compared to 3.3.
-#
-# Version 3.5 checks if there is L1 cache aliasing between user-supplied
-# key schedule and S-boxes and abstains from copying the former if
-# there is no. This allows end-user to consciously retain small block
-# performance by aligning key schedule in specific manner.
-#
-# Version 3.6 compresses Td4 to 256 bytes and prefetches it in ECB.
-#
-# Current ECB performance numbers for 128-bit key in CPU cycles per
-# processed byte [measure commonly used by AES benchmarkers] are:
-#
-#              small footprint         fully unrolled
-# P4           24                      22
-# AMD K8       20                      19
-# PIII         25                      23
-# Pentium      81                      78
-#
-# Version 3.7 reimplements outer rounds as "compact." Meaning that
-# first and last rounds reference compact 256 bytes S-box. This means
-# that first round consumes a lot more CPU cycles and that encrypt
-# and decrypt performance becomes asymmetric. Encrypt performance
-# drops by 10-12%, while decrypt - by 20-25%:-( 256 bytes S-box is
-# aggressively pre-fetched.
-#
-# Version 4.0 effectively rolls back to 3.6 and instead implements
-# additional set of functions, _[x86|sse]_AES_[en|de]crypt_compact,
-# which use exclusively 256 byte S-box. These functions are to be
-# called in modes not concealing plain text, such as ECB, or when
-# we're asked to process smaller amount of data [or unconditionally
-# on hyper-threading CPU]. Currently it's called unconditionally from
-# AES_[en|de]crypt, which affects all modes, but CBC. CBC routine
-# still needs to be modified to switch between slower and faster
-# mode when appropriate... But in either case benchmark landscape
-# changes dramatically and below numbers are CPU cycles per processed
-# byte for 128-bit key.
-#
-#              ECB encrypt     ECB decrypt     CBC large chunk
-# P4           52[54]          83[95]          23
-# AMD K8       46[41]          66[70]          18
-# PIII         41[50]          60[77]          24
-# Core 2       31[36]          45[64]          18.5
-# Atom         76[100]         96[138]         60
-# Pentium      115             150             77
-#
-# Version 4.1 switches to compact S-box even in key schedule setup.
-#
-# Version 4.2 prefetches compact S-box in every SSE round or in other
-# words every cache-line is *guaranteed* to be accessed within ~50
-# cycles window. Why just SSE? Because it's needed on hyper-threading
-# CPU! Which is also why it's prefetched with 64 byte stride. Best
-# part is that it has no negative effect on performance:-)
-#
-# Version 4.3 implements switch between compact and non-compact block
-# functions in AES_cbc_encrypt depending on how much data was asked
-# to be processed in one stroke.
-#
-######################################################################
-# Timing attacks are classified in two classes: synchronous when
-# attacker consciously initiates cryptographic operation and collects
-# timing data of various character afterwards, and asynchronous when
-# malicious code is executed on same CPU simultaneously with AES,
-# instruments itself and performs statistical analysis of this data.
-#
-# As far as synchronous attacks go the root to the AES timing
-# vulnerability is twofold. Firstly, of 256 S-box elements at most 160
-# are referred to in single 128-bit block operation. Well, in C
-# implementation with 4 distinct tables it's actually as little as 40
-# references per 256 elements table, but anyway... Secondly, even
-# though S-box elements are clustered into smaller amount of cache-
-# lines, smaller than 160 and even 40, it turned out that for certain
-# plain-text pattern[s] or simply put chosen plain-text and given key
-# few cache-lines remain unaccessed during block operation. Now, if
-# attacker can figure out this access pattern, he can deduct the key
-# [or at least part of it]. The natural way to mitigate this kind of
-# attacks is to minimize the amount of cache-lines in S-box and/or
-# prefetch them to ensure that every one is accessed for more uniform
-# timing. But note that *if* plain-text was concealed in such way that
-# input to block function is distributed *uniformly*, then attack
-# wouldn't apply. Now note that some encryption modes, most notably
-# CBC, do mask the plain-text in this exact way [secure cipher output
-# is distributed uniformly]. Yes, one still might find input that
-# would reveal the information about given key, but if amount of
-# candidate inputs to be tried is larger than amount of possible key
-# combinations then attack becomes infeasible. This is why revised
-# AES_cbc_encrypt "dares" to switch to larger S-box when larger chunk
-# of data is to be processed in one stroke. The current size limit of
-# 512 bytes is chosen to provide same [diminishingly low] probability
-# for cache-line to remain untouched in large chunk operation with
-# large S-box as for single block operation with compact S-box and
-# surely needs more careful consideration...
-#
-# As for asynchronous attacks. There are two flavours: attacker code
-# being interleaved with AES on hyper-threading CPU at *instruction*
-# level, and two processes time sharing single core. As for latter.
-# Two vectors. 1. Given that attacker process has higher priority,
-# yield execution to process performing AES just before timer fires
-# off the scheduler, immediately regain control of CPU and analyze the
-# cache state. For this attack to be efficient attacker would have to
-# effectively slow down the operation by several *orders* of magnitude,
-# by ratio of time slice to duration of handful of AES rounds, which
-# unlikely to remain unnoticed. Not to mention that this also means
-# that he would spend correspondingly more time to collect enough
-# statistical data to mount the attack. It's probably appropriate to
-# say that if adversary reckons that this attack is beneficial and
-# risks to be noticed, you probably have larger problems having him
-# mere opportunity. In other words suggested code design expects you
-# to preclude/mitigate this attack by overall system security design.
-# 2. Attacker manages to make his code interrupt driven. In order for
-# this kind of attack to be feasible, interrupt rate has to be high
-# enough, again comparable to duration of handful of AES rounds. But
-# is there interrupt source of such rate? Hardly, not even 1Gbps NIC
-# generates interrupts at such raging rate...
-#
-# And now back to the former, hyper-threading CPU or more specifically
-# Intel P4. Recall that asynchronous attack implies that malicious
-# code instruments itself. And naturally instrumentation granularity
-# has be noticeably lower than duration of codepath accessing S-box.
-# Given that all cache-lines are accessed during that time that is.
-# Current implementation accesses *all* cache-lines within ~50 cycles
-# window, which is actually *less* than RDTSC latency on Intel P4!
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC,"${dir}","${dir}../../perlasm");
-require "x86asm.pl";
-
-$output = pop;
-open OUT,">$output";
-*STDOUT=*OUT;
-
-&asm_init($ARGV[0],$x86only = $ARGV[$#ARGV] eq "386");
-&static_label("AES_Te");
-&static_label("AES_Td");
-
-$s0="eax";
-$s1="ebx";
-$s2="ecx";
-$s3="edx";
-$key="edi";
-$acc="esi";
-$tbl="ebp";
-
-# stack frame layout in _[x86|sse]_AES_* routines, frame is allocated
-# by caller
-$__ra=&DWP(0,"esp");   # return address
-$__s0=&DWP(4,"esp");   # s0 backing store
-$__s1=&DWP(8,"esp");   # s1 backing store
-$__s2=&DWP(12,"esp");  # s2 backing store
-$__s3=&DWP(16,"esp");  # s3 backing store
-$__key=&DWP(20,"esp"); # pointer to key schedule
-$__end=&DWP(24,"esp"); # pointer to end of key schedule
-$__tbl=&DWP(28,"esp"); # %ebp backing store
-
-# stack frame layout in AES_[en|crypt] routines, which differs from
-# above by 4 and overlaps by %ebp backing store
-$_tbl=&DWP(24,"esp");
-$_esp=&DWP(28,"esp");
-
-sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
-
-$speed_limit=512;      # chunks smaller than $speed_limit are
-                       # processed with compact routine in CBC mode
-$small_footprint=1;    # $small_footprint=1 code is ~5% slower [on
-                       # recent Âµ-archs], but ~5 times smaller!
-                       # I favor compact code to minimize cache
-                       # contention and in hope to "collect" 5% back
-                       # in real-life applications...
-
-$vertical_spin=0;      # shift "vertically" defaults to 0, because of
-                       # its proof-of-concept status...
-# Note that there is no decvert(), as well as last encryption round is
-# performed with "horizontal" shifts. This is because this "vertical"
-# implementation [one which groups shifts on a given $s[i] to form a
-# "column," unlike "horizontal" one, which groups shifts on different
-# $s[i] to form a "row"] is work in progress. It was observed to run
-# few percents faster on Intel cores, but not AMD. On AMD K8 core it's
-# whole 12% slower:-( So we face a trade-off... Shall it be resolved
-# some day? Till then the code is considered experimental and by
-# default remains dormant...
-
-sub encvert()
-{ my ($te,@s) = @_;
-  my ($v0,$v1) = ($acc,$key);
-
-       &mov    ($v0,$s[3]);                            # copy s3
-       &mov    (&DWP(4,"esp"),$s[2]);                  # save s2
-       &mov    ($v1,$s[0]);                            # copy s0
-       &mov    (&DWP(8,"esp"),$s[1]);                  # save s1
-
-       &movz   ($s[2],&HB($s[0]));
-       &and    ($s[0],0xFF);
-       &mov    ($s[0],&DWP(0,$te,$s[0],8));            # s0>>0
-       &shr    ($v1,16);
-       &mov    ($s[3],&DWP(3,$te,$s[2],8));            # s0>>8
-       &movz   ($s[1],&HB($v1));
-       &and    ($v1,0xFF);
-       &mov    ($s[2],&DWP(2,$te,$v1,8));              # s0>>16
-        &mov   ($v1,$v0);
-       &mov    ($s[1],&DWP(1,$te,$s[1],8));            # s0>>24
-
-       &and    ($v0,0xFF);
-       &xor    ($s[3],&DWP(0,$te,$v0,8));              # s3>>0
-       &movz   ($v0,&HB($v1));
-       &shr    ($v1,16);
-       &xor    ($s[2],&DWP(3,$te,$v0,8));              # s3>>8
-       &movz   ($v0,&HB($v1));
-       &and    ($v1,0xFF);
-       &xor    ($s[1],&DWP(2,$te,$v1,8));              # s3>>16
-        &mov   ($v1,&DWP(4,"esp"));                    # restore s2
-       &xor    ($s[0],&DWP(1,$te,$v0,8));              # s3>>24
-
-       &mov    ($v0,$v1);
-       &and    ($v1,0xFF);
-       &xor    ($s[2],&DWP(0,$te,$v1,8));              # s2>>0
-       &movz   ($v1,&HB($v0));
-       &shr    ($v0,16);
-       &xor    ($s[1],&DWP(3,$te,$v1,8));              # s2>>8
-       &movz   ($v1,&HB($v0));
-       &and    ($v0,0xFF);
-       &xor    ($s[0],&DWP(2,$te,$v0,8));              # s2>>16
-        &mov   ($v0,&DWP(8,"esp"));                    # restore s1
-       &xor    ($s[3],&DWP(1,$te,$v1,8));              # s2>>24
-
-       &mov    ($v1,$v0);
-       &and    ($v0,0xFF);
-       &xor    ($s[1],&DWP(0,$te,$v0,8));              # s1>>0
-       &movz   ($v0,&HB($v1));
-       &shr    ($v1,16);
-       &xor    ($s[0],&DWP(3,$te,$v0,8));              # s1>>8
-       &movz   ($v0,&HB($v1));
-       &and    ($v1,0xFF);
-       &xor    ($s[3],&DWP(2,$te,$v1,8));              # s1>>16
-        &mov   ($key,$__key);                          # reincarnate v1 as key
-       &xor    ($s[2],&DWP(1,$te,$v0,8));              # s1>>24
-}
-
-# Another experimental routine, which features "horizontal spin," but
-# eliminates one reference to stack. Strangely enough runs slower...
-sub enchoriz()
-{ my ($v0,$v1) = ($key,$acc);
-
-       &movz   ($v0,&LB($s0));                 #  3, 2, 1, 0*
-       &rotr   ($s2,8);                        #  8,11,10, 9
-       &mov    ($v1,&DWP(0,$te,$v0,8));        #  0
-       &movz   ($v0,&HB($s1));                 #  7, 6, 5*, 4
-       &rotr   ($s3,16);                       # 13,12,15,14
-       &xor    ($v1,&DWP(3,$te,$v0,8));        #  5
-       &movz   ($v0,&HB($s2));                 #  8,11,10*, 9
-       &rotr   ($s0,16);                       #  1, 0, 3, 2
-       &xor    ($v1,&DWP(2,$te,$v0,8));        # 10
-       &movz   ($v0,&HB($s3));                 # 13,12,15*,14
-       &xor    ($v1,&DWP(1,$te,$v0,8));        # 15, t[0] collected
-       &mov    ($__s0,$v1);                    # t[0] saved
-
-       &movz   ($v0,&LB($s1));                 #  7, 6, 5, 4*
-       &shr    ($s1,16);                       #  -, -, 7, 6
-       &mov    ($v1,&DWP(0,$te,$v0,8));        #  4
-       &movz   ($v0,&LB($s3));                 # 13,12,15,14*
-       &xor    ($v1,&DWP(2,$te,$v0,8));        # 14
-       &movz   ($v0,&HB($s0));                 #  1, 0, 3*, 2
-       &and    ($s3,0xffff0000);               # 13,12, -, -
-       &xor    ($v1,&DWP(1,$te,$v0,8));        #  3
-       &movz   ($v0,&LB($s2));                 #  8,11,10, 9*
-       &or     ($s3,$s1);                      # 13,12, 7, 6
-       &xor    ($v1,&DWP(3,$te,$v0,8));        #  9, t[1] collected
-       &mov    ($s1,$v1);                      #  s[1]=t[1]
-
-       &movz   ($v0,&LB($s0));                 #  1, 0, 3, 2*
-       &shr    ($s2,16);                       #  -, -, 8,11
-       &mov    ($v1,&DWP(2,$te,$v0,8));        #  2
-       &movz   ($v0,&HB($s3));                 # 13,12, 7*, 6
-       &xor    ($v1,&DWP(1,$te,$v0,8));        #  7
-       &movz   ($v0,&HB($s2));                 #  -, -, 8*,11
-       &xor    ($v1,&DWP(0,$te,$v0,8));        #  8
-       &mov    ($v0,$s3);
-       &shr    ($v0,24);                       # 13
-       &xor    ($v1,&DWP(3,$te,$v0,8));        # 13, t[2] collected
-
-       &movz   ($v0,&LB($s2));                 #  -, -, 8,11*
-       &shr    ($s0,24);                       #  1*
-       &mov    ($s2,&DWP(1,$te,$v0,8));        # 11
-       &xor    ($s2,&DWP(3,$te,$s0,8));        #  1
-       &mov    ($s0,$__s0);                    # s[0]=t[0]
-       &movz   ($v0,&LB($s3));                 # 13,12, 7, 6*
-       &shr    ($s3,16);                       #   ,  ,13,12
-       &xor    ($s2,&DWP(2,$te,$v0,8));        #  6
-       &mov    ($key,$__key);                  # reincarnate v0 as key
-       &and    ($s3,0xff);                     #   ,  ,13,12*
-       &mov    ($s3,&DWP(0,$te,$s3,8));        # 12
-       &xor    ($s3,$s2);                      # s[2]=t[3] collected
-       &mov    ($s2,$v1);                      # s[2]=t[2]
-}
-
-# More experimental code... SSE one... Even though this one eliminates
-# *all* references to stack, it's not faster...
-sub sse_encbody()
-{
-       &movz   ($acc,&LB("eax"));              #  0
-       &mov    ("ecx",&DWP(0,$tbl,$acc,8));    #  0
-       &pshufw ("mm2","mm0",0x0d);             #  7, 6, 3, 2
-       &movz   ("edx",&HB("eax"));             #  1
-       &mov    ("edx",&DWP(3,$tbl,"edx",8));   #  1
-       &shr    ("eax",16);                     #  5, 4
-
-       &movz   ($acc,&LB("ebx"));              # 10
-       &xor    ("ecx",&DWP(2,$tbl,$acc,8));    # 10
-       &pshufw ("mm6","mm4",0x08);             # 13,12, 9, 8
-       &movz   ($acc,&HB("ebx"));              # 11
-       &xor    ("edx",&DWP(1,$tbl,$acc,8));    # 11
-       &shr    ("ebx",16);                     # 15,14
-
-       &movz   ($acc,&HB("eax"));              #  5
-       &xor    ("ecx",&DWP(3,$tbl,$acc,8));    #  5
-       &movq   ("mm3",QWP(16,$key));
-       &movz   ($acc,&HB("ebx"));              # 15
-       &xor    ("ecx",&DWP(1,$tbl,$acc,8));    # 15
-       &movd   ("mm0","ecx");                  # t[0] collected
-
-       &movz   ($acc,&LB("eax"));              #  4
-       &mov    ("ecx",&DWP(0,$tbl,$acc,8));    #  4
-       &movd   ("eax","mm2");                  #  7, 6, 3, 2
-       &movz   ($acc,&LB("ebx"));              # 14
-       &xor    ("ecx",&DWP(2,$tbl,$acc,8));    # 14
-       &movd   ("ebx","mm6");                  # 13,12, 9, 8
-
-       &movz   ($acc,&HB("eax"));              #  3
-       &xor    ("ecx",&DWP(1,$tbl,$acc,8));    #  3
-       &movz   ($acc,&HB("ebx"));              #  9
-       &xor    ("ecx",&DWP(3,$tbl,$acc,8));    #  9
-       &movd   ("mm1","ecx");                  # t[1] collected
-
-       &movz   ($acc,&LB("eax"));              #  2
-       &mov    ("ecx",&DWP(2,$tbl,$acc,8));    #  2
-       &shr    ("eax",16);                     #  7, 6
-       &punpckldq      ("mm0","mm1");          # t[0,1] collected
-       &movz   ($acc,&LB("ebx"));              #  8
-       &xor    ("ecx",&DWP(0,$tbl,$acc,8));    #  8
-       &shr    ("ebx",16);                     # 13,12
-
-       &movz   ($acc,&HB("eax"));              #  7
-       &xor    ("ecx",&DWP(1,$tbl,$acc,8));    #  7
-       &pxor   ("mm0","mm3");
-       &movz   ("eax",&LB("eax"));             #  6
-       &xor    ("edx",&DWP(2,$tbl,"eax",8));   #  6
-       &pshufw ("mm1","mm0",0x08);             #  5, 4, 1, 0
-       &movz   ($acc,&HB("ebx"));              # 13
-       &xor    ("ecx",&DWP(3,$tbl,$acc,8));    # 13
-       &xor    ("ecx",&DWP(24,$key));          # t[2]
-       &movd   ("mm4","ecx");                  # t[2] collected
-       &movz   ("ebx",&LB("ebx"));             # 12
-       &xor    ("edx",&DWP(0,$tbl,"ebx",8));   # 12
-       &shr    ("ecx",16);
-       &movd   ("eax","mm1");                  #  5, 4, 1, 0
-       &mov    ("ebx",&DWP(28,$key));          # t[3]
-       &xor    ("ebx","edx");
-       &movd   ("mm5","ebx");                  # t[3] collected
-       &and    ("ebx",0xffff0000);
-       &or     ("ebx","ecx");
-
-       &punpckldq      ("mm4","mm5");          # t[2,3] collected
-}
-
-######################################################################
-# "Compact" block function
-######################################################################
-
-sub enccompact()
-{ my $Fn = \&mov;
-  while ($#_>5) { pop(@_); $Fn=sub{}; }
-  my ($i,$te,@s)=@_;
-  my $tmp = $key;
-  my $out = $i==3?$s[0]:$acc;
-
-       # $Fn is used in first compact round and its purpose is to
-       # void restoration of some values from stack, so that after
-       # 4xenccompact with extra argument $key value is left there...
-       if ($i==3)  {   &$Fn    ($key,$__key);                  }##%edx
-       else        {   &mov    ($out,$s[0]);                   }
-                       &and    ($out,0xFF);
-       if ($i==1)  {   &shr    ($s[0],16);                     }#%ebx[1]
-       if ($i==2)  {   &shr    ($s[0],24);                     }#%ecx[2]
-                       &movz   ($out,&BP(-128,$te,$out,1));
-
-       if ($i==3)  {   $tmp=$s[1];                             }##%eax
-                       &movz   ($tmp,&HB($s[1]));
-                       &movz   ($tmp,&BP(-128,$te,$tmp,1));
-                       &shl    ($tmp,8);
-                       &xor    ($out,$tmp);
-
-       if ($i==3)  {   $tmp=$s[2]; &mov ($s[1],$__s0);         }##%ebx
-       else        {   &mov    ($tmp,$s[2]);
-                       &shr    ($tmp,16);                      }
-       if ($i==2)  {   &and    ($s[1],0xFF);                   }#%edx[2]
-                       &and    ($tmp,0xFF);
-                       &movz   ($tmp,&BP(-128,$te,$tmp,1));
-                       &shl    ($tmp,16);
-                       &xor    ($out,$tmp);
-
-       if ($i==3)  {   $tmp=$s[3]; &mov ($s[2],$__s1);         }##%ecx
-       elsif($i==2){   &movz   ($tmp,&HB($s[3]));              }#%ebx[2]
-       else        {   &mov    ($tmp,$s[3]);
-                       &shr    ($tmp,24);                      }
-                       &movz   ($tmp,&BP(-128,$te,$tmp,1));
-                       &shl    ($tmp,24);
-                       &xor    ($out,$tmp);
-       if ($i<2)   {   &mov    (&DWP(4+4*$i,"esp"),$out);      }
-       if ($i==3)  {   &mov    ($s[3],$acc);                   }
-       &comment();
-}
-
-sub enctransform()
-{ my @s = ($s0,$s1,$s2,$s3);
-  my $i = shift;
-  my $tmp = $tbl;
-  my $r2  = $key ;
-
-       &and    ($tmp,$s[$i]);
-       &lea    ($r2,&DWP(0,$s[$i],$s[$i]));
-       &mov    ($acc,$tmp);
-       &shr    ($tmp,7);
-       &and    ($r2,0xfefefefe);
-       &sub    ($acc,$tmp);
-       &mov    ($tmp,$s[$i]);
-       &and    ($acc,0x1b1b1b1b);
-       &rotr   ($tmp,16);
-       &xor    ($acc,$r2);     # r2
-       &mov    ($r2,$s[$i]);
-
-       &xor    ($s[$i],$acc);  # r0 ^ r2
-       &rotr   ($r2,16+8);
-       &xor    ($acc,$tmp);
-       &rotl   ($s[$i],24);
-       &xor    ($acc,$r2);
-       &mov    ($tmp,0x80808080)       if ($i!=1);
-       &xor    ($s[$i],$acc);  # ROTATE(r2^r0,24) ^ r2
-}
-
-&function_begin_B("_x86_AES_encrypt_compact");
-       # note that caller is expected to allocate stack frame for me!
-       &mov    ($__key,$key);                  # save key
-
-       &xor    ($s0,&DWP(0,$key));             # xor with key
-       &xor    ($s1,&DWP(4,$key));
-       &xor    ($s2,&DWP(8,$key));
-       &xor    ($s3,&DWP(12,$key));
-
-       &mov    ($acc,&DWP(240,$key));          # load key->rounds
-       &lea    ($acc,&DWP(-2,$acc,$acc));
-       &lea    ($acc,&DWP(0,$key,$acc,8));
-       &mov    ($__end,$acc);                  # end of key schedule
-
-       # prefetch Te4
-       &mov    ($key,&DWP(0-128,$tbl));
-       &mov    ($acc,&DWP(32-128,$tbl));
-       &mov    ($key,&DWP(64-128,$tbl));
-       &mov    ($acc,&DWP(96-128,$tbl));
-       &mov    ($key,&DWP(128-128,$tbl));
-       &mov    ($acc,&DWP(160-128,$tbl));
-       &mov    ($key,&DWP(192-128,$tbl));
-       &mov    ($acc,&DWP(224-128,$tbl));
-
-       &set_label("loop",16);
-
-               &enccompact(0,$tbl,$s0,$s1,$s2,$s3,1);
-               &enccompact(1,$tbl,$s1,$s2,$s3,$s0,1);
-               &enccompact(2,$tbl,$s2,$s3,$s0,$s1,1);
-               &enccompact(3,$tbl,$s3,$s0,$s1,$s2,1);
-               &mov    ($tbl,0x80808080);
-               &enctransform(2);
-               &enctransform(3);
-               &enctransform(0);
-               &enctransform(1);
-               &mov    ($key,$__key);
-               &mov    ($tbl,$__tbl);
-               &add    ($key,16);              # advance rd_key
-               &xor    ($s0,&DWP(0,$key));
-               &xor    ($s1,&DWP(4,$key));
-               &xor    ($s2,&DWP(8,$key));
-               &xor    ($s3,&DWP(12,$key));
-
-       &cmp    ($key,$__end);
-       &mov    ($__key,$key);
-       &jb     (&label("loop"));
-
-       &enccompact(0,$tbl,$s0,$s1,$s2,$s3);
-       &enccompact(1,$tbl,$s1,$s2,$s3,$s0);
-       &enccompact(2,$tbl,$s2,$s3,$s0,$s1);
-       &enccompact(3,$tbl,$s3,$s0,$s1,$s2);
-
-       &xor    ($s0,&DWP(16,$key));
-       &xor    ($s1,&DWP(20,$key));
-       &xor    ($s2,&DWP(24,$key));
-       &xor    ($s3,&DWP(28,$key));
-
-       &ret    ();
-&function_end_B("_x86_AES_encrypt_compact");
-
-######################################################################
-# "Compact" SSE block function.
-######################################################################
-#
-# Performance is not actually extraordinary in comparison to pure
-# x86 code. In particular encrypt performance is virtually the same.
-# Decrypt performance on the other hand is 15-20% better on newer
-# Âµ-archs [but we're thankful for *any* improvement here], and ~50%
-# better on PIII:-) And additionally on the pros side this code
-# eliminates redundant references to stack and thus relieves/
-# minimizes the pressure on the memory bus.
-#
-# MMX register layout                           lsb
-# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-# |          mm4          |          mm0          |
-# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-# |     s3    |     s2    |     s1    |     s0    |
-# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-# |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-#
-# Indexes translate as s[N/4]>>(8*(N%4)), e.g. 5 means s1>>8.
-# In this terms encryption and decryption "compact" permutation
-# matrices can be depicted as following:
-#
-# encryption              lsb  # decryption              lsb
-# +----++----+----+----+----+  # +----++----+----+----+----+
-# | t0 || 15 | 10 |  5 |  0 |  # | t0 ||  7 | 10 | 13 |  0 |
-# +----++----+----+----+----+  # +----++----+----+----+----+
-# | t1 ||  3 | 14 |  9 |  4 |  # | t1 || 11 | 14 |  1 |  4 |
-# +----++----+----+----+----+  # +----++----+----+----+----+
-# | t2 ||  7 |  2 | 13 |  8 |  # | t2 || 15 |  2 |  5 |  8 |
-# +----++----+----+----+----+  # +----++----+----+----+----+
-# | t3 || 11 |  6 |  1 | 12 |  # | t3 ||  3 |  6 |  9 | 12 |
-# +----++----+----+----+----+  # +----++----+----+----+----+
-#
-######################################################################
-# Why not xmm registers? Short answer. It was actually tested and
-# was not any faster, but *contrary*, most notably on Intel CPUs.
-# Longer answer. Main advantage of using mm registers is that movd
-# latency is lower, especially on Intel P4. While arithmetic
-# instructions are twice as many, they can be scheduled every cycle
-# and not every second one when they are operating on xmm register,
-# so that "arithmetic throughput" remains virtually the same. And
-# finally the code can be executed even on elder SSE-only CPUs:-)
-
-sub sse_enccompact()
-{
-       &pshufw ("mm1","mm0",0x08);             #  5, 4, 1, 0
-       &pshufw ("mm5","mm4",0x0d);             # 15,14,11,10
-       &movd   ("eax","mm1");                  #  5, 4, 1, 0
-       &movd   ("ebx","mm5");                  # 15,14,11,10
-       &mov    ($__key,$key);
-
-       &movz   ($acc,&LB("eax"));              #  0
-       &movz   ("edx",&HB("eax"));             #  1
-       &pshufw ("mm2","mm0",0x0d);             #  7, 6, 3, 2
-       &movz   ("ecx",&BP(-128,$tbl,$acc,1));  #  0
-       &movz   ($key,&LB("ebx"));              # 10
-       &movz   ("edx",&BP(-128,$tbl,"edx",1)); #  1
-       &shr    ("eax",16);                     #  5, 4
-       &shl    ("edx",8);                      #  1
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   # 10
-       &movz   ($key,&HB("ebx"));              # 11
-       &shl    ($acc,16);                      # 10
-       &pshufw ("mm6","mm4",0x08);             # 13,12, 9, 8
-       &or     ("ecx",$acc);                   # 10
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   # 11
-       &movz   ($key,&HB("eax"));              #  5
-       &shl    ($acc,24);                      # 11
-       &shr    ("ebx",16);                     # 15,14
-       &or     ("edx",$acc);                   # 11
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  5
-       &movz   ($key,&HB("ebx"));              # 15
-       &shl    ($acc,8);                       #  5
-       &or     ("ecx",$acc);                   #  5
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   # 15
-       &movz   ($key,&LB("eax"));              #  4
-       &shl    ($acc,24);                      # 15
-       &or     ("ecx",$acc);                   # 15
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  4
-       &movz   ($key,&LB("ebx"));              # 14
-       &movd   ("eax","mm2");                  #  7, 6, 3, 2
-       &movd   ("mm0","ecx");                  # t[0] collected
-       &movz   ("ecx",&BP(-128,$tbl,$key,1));  # 14
-       &movz   ($key,&HB("eax"));              #  3
-       &shl    ("ecx",16);                     # 14
-       &movd   ("ebx","mm6");                  # 13,12, 9, 8
-       &or     ("ecx",$acc);                   # 14
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  3
-       &movz   ($key,&HB("ebx"));              #  9
-       &shl    ($acc,24);                      #  3
-       &or     ("ecx",$acc);                   #  3
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  9
-       &movz   ($key,&LB("ebx"));              #  8
-       &shl    ($acc,8);                       #  9
-       &shr    ("ebx",16);                     # 13,12
-       &or     ("ecx",$acc);                   #  9
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  8
-       &movz   ($key,&LB("eax"));              #  2
-       &shr    ("eax",16);                     #  7, 6
-       &movd   ("mm1","ecx");                  # t[1] collected
-       &movz   ("ecx",&BP(-128,$tbl,$key,1));  #  2
-       &movz   ($key,&HB("eax"));              #  7
-       &shl    ("ecx",16);                     #  2
-       &and    ("eax",0xff);                   #  6
-       &or     ("ecx",$acc);                   #  2
-
-       &punpckldq      ("mm0","mm1");          # t[0,1] collected
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  7
-       &movz   ($key,&HB("ebx"));              # 13
-       &shl    ($acc,24);                      #  7
-       &and    ("ebx",0xff);                   # 12
-       &movz   ("eax",&BP(-128,$tbl,"eax",1)); #  6
-       &or     ("ecx",$acc);                   #  7
-       &shl    ("eax",16);                     #  6
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   # 13
-       &or     ("edx","eax");                  #  6
-       &shl    ($acc,8);                       # 13
-       &movz   ("ebx",&BP(-128,$tbl,"ebx",1)); # 12
-       &or     ("ecx",$acc);                   # 13
-       &or     ("edx","ebx");                  # 12
-       &mov    ($key,$__key);
-       &movd   ("mm4","ecx");                  # t[2] collected
-       &movd   ("mm5","edx");                  # t[3] collected
-
-       &punpckldq      ("mm4","mm5");          # t[2,3] collected
-}
-
-                                       if (!$x86only) {
-&function_begin_B("_sse_AES_encrypt_compact");
-       &pxor   ("mm0",&QWP(0,$key));   #  7, 6, 5, 4, 3, 2, 1, 0
-       &pxor   ("mm4",&QWP(8,$key));   # 15,14,13,12,11,10, 9, 8
-
-       # note that caller is expected to allocate stack frame for me!
-       &mov    ($acc,&DWP(240,$key));          # load key->rounds
-       &lea    ($acc,&DWP(-2,$acc,$acc));
-       &lea    ($acc,&DWP(0,$key,$acc,8));
-       &mov    ($__end,$acc);                  # end of key schedule
-
-       &mov    ($s0,0x1b1b1b1b);               # magic constant
-       &mov    (&DWP(8,"esp"),$s0);
-       &mov    (&DWP(12,"esp"),$s0);
-
-       # prefetch Te4
-       &mov    ($s0,&DWP(0-128,$tbl));
-       &mov    ($s1,&DWP(32-128,$tbl));
-       &mov    ($s2,&DWP(64-128,$tbl));
-       &mov    ($s3,&DWP(96-128,$tbl));
-       &mov    ($s0,&DWP(128-128,$tbl));
-       &mov    ($s1,&DWP(160-128,$tbl));
-       &mov    ($s2,&DWP(192-128,$tbl));
-       &mov    ($s3,&DWP(224-128,$tbl));
-
-       &set_label("loop",16);
-               &sse_enccompact();
-               &add    ($key,16);
-               &cmp    ($key,$__end);
-               &ja     (&label("out"));
-
-               &movq   ("mm2",&QWP(8,"esp"));
-               &pxor   ("mm3","mm3");          &pxor   ("mm7","mm7");
-               &movq   ("mm1","mm0");          &movq   ("mm5","mm4");  # r0
-               &pcmpgtb("mm3","mm0");          &pcmpgtb("mm7","mm4");
-               &pand   ("mm3","mm2");          &pand   ("mm7","mm2");
-               &pshufw ("mm2","mm0",0xb1);     &pshufw ("mm6","mm4",0xb1);# ROTATE(r0,16)
-               &paddb  ("mm0","mm0");          &paddb  ("mm4","mm4");
-               &pxor   ("mm0","mm3");          &pxor   ("mm4","mm7");  # = r2
-               &pshufw ("mm3","mm2",0xb1);     &pshufw ("mm7","mm6",0xb1);# r0
-               &pxor   ("mm1","mm0");          &pxor   ("mm5","mm4");  # r0^r2
-               &pxor   ("mm0","mm2");          &pxor   ("mm4","mm6");  # ^= ROTATE(r0,16)
-
-               &movq   ("mm2","mm3");          &movq   ("mm6","mm7");
-               &pslld  ("mm3",8);              &pslld  ("mm7",8);
-               &psrld  ("mm2",24);             &psrld  ("mm6",24);
-               &pxor   ("mm0","mm3");          &pxor   ("mm4","mm7");  # ^= r0<<8
-               &pxor   ("mm0","mm2");          &pxor   ("mm4","mm6");  # ^= r0>>24
-
-               &movq   ("mm3","mm1");          &movq   ("mm7","mm5");
-               &movq   ("mm2",&QWP(0,$key));   &movq   ("mm6",&QWP(8,$key));
-               &psrld  ("mm1",8);              &psrld  ("mm5",8);
-               &mov    ($s0,&DWP(0-128,$tbl));
-               &pslld  ("mm3",24);             &pslld  ("mm7",24);
-               &mov    ($s1,&DWP(64-128,$tbl));
-               &pxor   ("mm0","mm1");          &pxor   ("mm4","mm5");  # ^= (r2^r0)<<8
-               &mov    ($s2,&DWP(128-128,$tbl));
-               &pxor   ("mm0","mm3");          &pxor   ("mm4","mm7");  # ^= (r2^r0)>>24
-               &mov    ($s3,&DWP(192-128,$tbl));
-
-               &pxor   ("mm0","mm2");          &pxor   ("mm4","mm6");
-       &jmp    (&label("loop"));
-
-       &set_label("out",16);
-       &pxor   ("mm0",&QWP(0,$key));
-       &pxor   ("mm4",&QWP(8,$key));
-
-       &ret    ();
-&function_end_B("_sse_AES_encrypt_compact");
-                                       }
-
-######################################################################
-# Vanilla block function.
-######################################################################
-
-sub encstep()
-{ my ($i,$te,@s) = @_;
-  my $tmp = $key;
-  my $out = $i==3?$s[0]:$acc;
-
-       # lines marked with #%e?x[i] denote "reordered" instructions...
-       if ($i==3)  {   &mov    ($key,$__key);                  }##%edx
-       else        {   &mov    ($out,$s[0]);
-                       &and    ($out,0xFF);                    }
-       if ($i==1)  {   &shr    ($s[0],16);                     }#%ebx[1]
-       if ($i==2)  {   &shr    ($s[0],24);                     }#%ecx[2]
-                       &mov    ($out,&DWP(0,$te,$out,8));
-
-       if ($i==3)  {   $tmp=$s[1];                             }##%eax
-                       &movz   ($tmp,&HB($s[1]));
-                       &xor    ($out,&DWP(3,$te,$tmp,8));
-
-       if ($i==3)  {   $tmp=$s[2]; &mov ($s[1],$__s0);         }##%ebx
-       else        {   &mov    ($tmp,$s[2]);
-                       &shr    ($tmp,16);                      }
-       if ($i==2)  {   &and    ($s[1],0xFF);                   }#%edx[2]
-                       &and    ($tmp,0xFF);
-                       &xor    ($out,&DWP(2,$te,$tmp,8));
-
-       if ($i==3)  {   $tmp=$s[3]; &mov ($s[2],$__s1);         }##%ecx
-       elsif($i==2){   &movz   ($tmp,&HB($s[3]));              }#%ebx[2]
-       else        {   &mov    ($tmp,$s[3]);
-                       &shr    ($tmp,24)                       }
-                       &xor    ($out,&DWP(1,$te,$tmp,8));
-       if ($i<2)   {   &mov    (&DWP(4+4*$i,"esp"),$out);      }
-       if ($i==3)  {   &mov    ($s[3],$acc);                   }
-                       &comment();
-}
-
-sub enclast()
-{ my ($i,$te,@s)=@_;
-  my $tmp = $key;
-  my $out = $i==3?$s[0]:$acc;
-
-       if ($i==3)  {   &mov    ($key,$__key);                  }##%edx
-       else        {   &mov    ($out,$s[0]);                   }
-                       &and    ($out,0xFF);
-       if ($i==1)  {   &shr    ($s[0],16);                     }#%ebx[1]
-       if ($i==2)  {   &shr    ($s[0],24);                     }#%ecx[2]
-                       &mov    ($out,&DWP(2,$te,$out,8));
-                       &and    ($out,0x000000ff);
-
-       if ($i==3)  {   $tmp=$s[1];                             }##%eax
-                       &movz   ($tmp,&HB($s[1]));
-                       &mov    ($tmp,&DWP(0,$te,$tmp,8));
-                       &and    ($tmp,0x0000ff00);
-                       &xor    ($out,$tmp);
-
-       if ($i==3)  {   $tmp=$s[2]; &mov ($s[1],$__s0);         }##%ebx
-       else        {   &mov    ($tmp,$s[2]);
-                       &shr    ($tmp,16);                      }
-       if ($i==2)  {   &and    ($s[1],0xFF);                   }#%edx[2]
-                       &and    ($tmp,0xFF);
-                       &mov    ($tmp,&DWP(0,$te,$tmp,8));
-                       &and    ($tmp,0x00ff0000);
-                       &xor    ($out,$tmp);
-
-       if ($i==3)  {   $tmp=$s[3]; &mov ($s[2],$__s1);         }##%ecx
-       elsif($i==2){   &movz   ($tmp,&HB($s[3]));              }#%ebx[2]
-       else        {   &mov    ($tmp,$s[3]);
-                       &shr    ($tmp,24);                      }
-                       &mov    ($tmp,&DWP(2,$te,$tmp,8));
-                       &and    ($tmp,0xff000000);
-                       &xor    ($out,$tmp);
-       if ($i<2)   {   &mov    (&DWP(4+4*$i,"esp"),$out);      }
-       if ($i==3)  {   &mov    ($s[3],$acc);                   }
-}
-
-&function_begin_B("_x86_AES_encrypt");
-       if ($vertical_spin) {
-               # I need high parts of volatile registers to be accessible...
-               &exch   ($s1="edi",$key="ebx");
-               &mov    ($s2="esi",$acc="ecx");
-       }
-
-       # note that caller is expected to allocate stack frame for me!
-       &mov    ($__key,$key);                  # save key
-
-       &xor    ($s0,&DWP(0,$key));             # xor with key
-       &xor    ($s1,&DWP(4,$key));
-       &xor    ($s2,&DWP(8,$key));
-       &xor    ($s3,&DWP(12,$key));
-
-       &mov    ($acc,&DWP(240,$key));          # load key->rounds
-
-       if ($small_footprint) {
-           &lea        ($acc,&DWP(-2,$acc,$acc));
-           &lea        ($acc,&DWP(0,$key,$acc,8));
-           &mov        ($__end,$acc);          # end of key schedule
-
-           &set_label("loop",16);
-               if ($vertical_spin) {
-                   &encvert($tbl,$s0,$s1,$s2,$s3);
-               } else {
-                   &encstep(0,$tbl,$s0,$s1,$s2,$s3);
-                   &encstep(1,$tbl,$s1,$s2,$s3,$s0);
-                   &encstep(2,$tbl,$s2,$s3,$s0,$s1);
-                   &encstep(3,$tbl,$s3,$s0,$s1,$s2);
-               }
-               &add    ($key,16);              # advance rd_key
-               &xor    ($s0,&DWP(0,$key));
-               &xor    ($s1,&DWP(4,$key));
-               &xor    ($s2,&DWP(8,$key));
-               &xor    ($s3,&DWP(12,$key));
-           &cmp        ($key,$__end);
-           &mov        ($__key,$key);
-           &jb         (&label("loop"));
-       }
-       else {
-           &cmp        ($acc,10);
-           &jle        (&label("10rounds"));
-           &cmp        ($acc,12);
-           &jle        (&label("12rounds"));
-
-       &set_label("14rounds",4);
-           for ($i=1;$i<3;$i++) {
-               if ($vertical_spin) {
-                   &encvert($tbl,$s0,$s1,$s2,$s3);
-               } else {
-                   &encstep(0,$tbl,$s0,$s1,$s2,$s3);
-                   &encstep(1,$tbl,$s1,$s2,$s3,$s0);
-                   &encstep(2,$tbl,$s2,$s3,$s0,$s1);
-                   &encstep(3,$tbl,$s3,$s0,$s1,$s2);
-               }
-               &xor    ($s0,&DWP(16*$i+0,$key));
-               &xor    ($s1,&DWP(16*$i+4,$key));
-               &xor    ($s2,&DWP(16*$i+8,$key));
-               &xor    ($s3,&DWP(16*$i+12,$key));
-           }
-           &add        ($key,32);
-           &mov        ($__key,$key);          # advance rd_key
-       &set_label("12rounds",4);
-           for ($i=1;$i<3;$i++) {
-               if ($vertical_spin) {
-                   &encvert($tbl,$s0,$s1,$s2,$s3);
-               } else {
-                   &encstep(0,$tbl,$s0,$s1,$s2,$s3);
-                   &encstep(1,$tbl,$s1,$s2,$s3,$s0);
-                   &encstep(2,$tbl,$s2,$s3,$s0,$s1);
-                   &encstep(3,$tbl,$s3,$s0,$s1,$s2);
-               }
-               &xor    ($s0,&DWP(16*$i+0,$key));
-               &xor    ($s1,&DWP(16*$i+4,$key));
-               &xor    ($s2,&DWP(16*$i+8,$key));
-               &xor    ($s3,&DWP(16*$i+12,$key));
-           }
-           &add        ($key,32);
-           &mov        ($__key,$key);          # advance rd_key
-       &set_label("10rounds",4);
-           for ($i=1;$i<10;$i++) {
-               if ($vertical_spin) {
-                   &encvert($tbl,$s0,$s1,$s2,$s3);
-               } else {
-                   &encstep(0,$tbl,$s0,$s1,$s2,$s3);
-                   &encstep(1,$tbl,$s1,$s2,$s3,$s0);
-                   &encstep(2,$tbl,$s2,$s3,$s0,$s1);
-                   &encstep(3,$tbl,$s3,$s0,$s1,$s2);
-               }
-               &xor    ($s0,&DWP(16*$i+0,$key));
-               &xor    ($s1,&DWP(16*$i+4,$key));
-               &xor    ($s2,&DWP(16*$i+8,$key));
-               &xor    ($s3,&DWP(16*$i+12,$key));
-           }
-       }
-
-       if ($vertical_spin) {
-           # "reincarnate" some registers for "horizontal" spin...
-           &mov        ($s1="ebx",$key="edi");
-           &mov        ($s2="ecx",$acc="esi");
-       }
-       &enclast(0,$tbl,$s0,$s1,$s2,$s3);
-       &enclast(1,$tbl,$s1,$s2,$s3,$s0);
-       &enclast(2,$tbl,$s2,$s3,$s0,$s1);
-       &enclast(3,$tbl,$s3,$s0,$s1,$s2);
-
-       &add    ($key,$small_footprint?16:160);
-       &xor    ($s0,&DWP(0,$key));
-       &xor    ($s1,&DWP(4,$key));
-       &xor    ($s2,&DWP(8,$key));
-       &xor    ($s3,&DWP(12,$key));
-
-       &ret    ();
-
-&set_label("AES_Te",64);       # Yes! I keep it in the code segment!
-       &_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
-       &_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
-       &_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56);
-       &_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec);
-       &_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa);
-       &_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb);
-       &_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45);
-       &_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b);
-       &_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c);
-       &_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83);
-       &_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9);
-       &_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a);
-       &_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d);
-       &_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f);
-       &_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df);
-       &_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea);
-       &_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34);
-       &_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b);
-       &_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d);
-       &_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413);
-       &_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1);
-       &_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6);
-       &_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972);
-       &_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85);
-       &_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed);
-       &_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511);
-       &_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe);
-       &_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b);
-       &_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05);
-       &_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1);
-       &_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142);
-       &_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf);
-       &_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3);
-       &_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e);
-       &_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a);
-       &_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6);
-       &_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3);
-       &_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b);
-       &_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428);
-       &_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad);
-       &_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14);
-       &_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8);
-       &_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4);
-       &_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2);
-       &_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda);
-       &_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949);
-       &_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf);
-       &_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810);
-       &_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c);
-       &_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697);
-       &_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e);
-       &_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f);
-       &_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc);
-       &_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c);
-       &_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969);
-       &_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27);
-       &_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122);
-       &_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433);
-       &_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9);
-       &_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5);
-       &_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a);
-       &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
-       &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
-       &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
-
-#Te4   # four copies of Te4 to choose from to avoid L1 aliasing
-       &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-       &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-       &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-       &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-       &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-       &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-       &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-       &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-       &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-       &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-       &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-       &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-       &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-       &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-       &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-       &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-       &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-       &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-       &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-       &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-       &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-       &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-       &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-       &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-       &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-       &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-       &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-       &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-       &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-       &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-       &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-       &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-
-       &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-       &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-       &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-       &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-       &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-       &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-       &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-       &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-       &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-       &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-       &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-       &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-       &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-       &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-       &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-       &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-       &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-       &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-       &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-       &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-       &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-       &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-       &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-       &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-       &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-       &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-       &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-       &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-       &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-       &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-       &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-       &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-
-       &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-       &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-       &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-       &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-       &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-       &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-       &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-       &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-       &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-       &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-       &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-       &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-       &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-       &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-       &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-       &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-       &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-       &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-       &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-       &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-       &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-       &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-       &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-       &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-       &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-       &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-       &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-       &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-       &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-       &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-       &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-       &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-
-       &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-       &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-       &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-       &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-       &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-       &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-       &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-       &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-       &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-       &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-       &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-       &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-       &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-       &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-       &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-       &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-       &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-       &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-       &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-       &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-       &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-       &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-       &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-       &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-       &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-       &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-       &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-       &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-       &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-       &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-       &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-       &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-#rcon:
-       &data_word(0x00000001, 0x00000002, 0x00000004, 0x00000008);
-       &data_word(0x00000010, 0x00000020, 0x00000040, 0x00000080);
-       &data_word(0x0000001b, 0x00000036, 0x00000000, 0x00000000);
-       &data_word(0x00000000, 0x00000000, 0x00000000, 0x00000000);
-&function_end_B("_x86_AES_encrypt");
-
-# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
-&function_begin("AES_encrypt");
-       &mov    ($acc,&wparam(0));              # load inp
-       &mov    ($key,&wparam(2));              # load key
-
-       &mov    ($s0,"esp");
-       &sub    ("esp",36);
-       &and    ("esp",-64);                    # align to cache-line
-
-       # place stack frame just "above" the key schedule
-       &lea    ($s1,&DWP(-64-63,$key));
-       &sub    ($s1,"esp");
-       &neg    ($s1);
-       &and    ($s1,0x3C0);    # modulo 1024, but aligned to cache-line
-       &sub    ("esp",$s1);
-       &add    ("esp",4);      # 4 is reserved for caller's return address
-       &mov    ($_esp,$s0);                    # save stack pointer
-
-       &call   (&label("pic_point"));          # make it PIC!
-       &set_label("pic_point");
-       &blindpop($tbl);
-       &picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if (!$x86only);
-       &lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
-
-       # pick Te4 copy which can't "overlap" with stack frame or key schedule
-       &lea    ($s1,&DWP(768-4,"esp"));
-       &sub    ($s1,$tbl);
-       &and    ($s1,0x300);
-       &lea    ($tbl,&DWP(2048+128,$tbl,$s1));
-
-                                       if (!$x86only) {
-       &bt     (&DWP(0,$s0),25);       # check for SSE bit
-       &jnc    (&label("x86"));
-
-       &movq   ("mm0",&QWP(0,$acc));
-       &movq   ("mm4",&QWP(8,$acc));
-       &call   ("_sse_AES_encrypt_compact");
-       &mov    ("esp",$_esp);                  # restore stack pointer
-       &mov    ($acc,&wparam(1));              # load out
-       &movq   (&QWP(0,$acc),"mm0");           # write output data
-       &movq   (&QWP(8,$acc),"mm4");
-       &emms   ();
-       &function_end_A();
-                                       }
-       &set_label("x86",16);
-       &mov    ($_tbl,$tbl);
-       &mov    ($s0,&DWP(0,$acc));             # load input data
-       &mov    ($s1,&DWP(4,$acc));
-       &mov    ($s2,&DWP(8,$acc));
-       &mov    ($s3,&DWP(12,$acc));
-       &call   ("_x86_AES_encrypt_compact");
-       &mov    ("esp",$_esp);                  # restore stack pointer
-       &mov    ($acc,&wparam(1));              # load out
-       &mov    (&DWP(0,$acc),$s0);             # write output data
-       &mov    (&DWP(4,$acc),$s1);
-       &mov    (&DWP(8,$acc),$s2);
-       &mov    (&DWP(12,$acc),$s3);
-&function_end("AES_encrypt");
-
-#--------------------------------------------------------------------#
-
-######################################################################
-# "Compact" block function
-######################################################################
-
-sub deccompact()
-{ my $Fn = \&mov;
-  while ($#_>5) { pop(@_); $Fn=sub{}; }
-  my ($i,$td,@s)=@_;
-  my $tmp = $key;
-  my $out = $i==3?$s[0]:$acc;
-
-       # $Fn is used in first compact round and its purpose is to
-       # void restoration of some values from stack, so that after
-       # 4xdeccompact with extra argument $key, $s0 and $s1 values
-       # are left there...
-       if($i==3)   {   &$Fn    ($key,$__key);                  }
-       else        {   &mov    ($out,$s[0]);                   }
-                       &and    ($out,0xFF);
-                       &movz   ($out,&BP(-128,$td,$out,1));
-
-       if ($i==3)  {   $tmp=$s[1];                             }
-                       &movz   ($tmp,&HB($s[1]));
-                       &movz   ($tmp,&BP(-128,$td,$tmp,1));
-                       &shl    ($tmp,8);
-                       &xor    ($out,$tmp);
-
-       if ($i==3)  {   $tmp=$s[2]; &mov ($s[1],$acc);          }
-       else        {   mov     ($tmp,$s[2]);                   }
-                       &shr    ($tmp,16);
-                       &and    ($tmp,0xFF);
-                       &movz   ($tmp,&BP(-128,$td,$tmp,1));
-                       &shl    ($tmp,16);
-                       &xor    ($out,$tmp);
-
-       if ($i==3)  {   $tmp=$s[3]; &$Fn ($s[2],$__s1);         }
-       else        {   &mov    ($tmp,$s[3]);                   }
-                       &shr    ($tmp,24);
-                       &movz   ($tmp,&BP(-128,$td,$tmp,1));
-                       &shl    ($tmp,24);
-                       &xor    ($out,$tmp);
-       if ($i<2)   {   &mov    (&DWP(4+4*$i,"esp"),$out);      }
-       if ($i==3)  {   &$Fn    ($s[3],$__s0);                  }
-}
-
-# must be called with 2,3,0,1 as argument sequence!!!
-sub dectransform()
-{ my @s = ($s0,$s1,$s2,$s3);
-  my $i = shift;
-  my $tmp = $key;
-  my $tp2 = @s[($i+2)%4]; $tp2 = @s[2] if ($i==1);
-  my $tp4 = @s[($i+3)%4]; $tp4 = @s[3] if ($i==1);
-  my $tp8 = $tbl;
-
-       &mov    ($tmp,0x80808080);
-       &and    ($tmp,$s[$i]);
-       &mov    ($acc,$tmp);
-       &shr    ($tmp,7);
-       &lea    ($tp2,&DWP(0,$s[$i],$s[$i]));
-       &sub    ($acc,$tmp);
-       &and    ($tp2,0xfefefefe);
-       &and    ($acc,0x1b1b1b1b);
-       &xor    ($tp2,$acc);
-       &mov    ($tmp,0x80808080);
-
-       &and    ($tmp,$tp2);
-       &mov    ($acc,$tmp);
-       &shr    ($tmp,7);
-       &lea    ($tp4,&DWP(0,$tp2,$tp2));
-       &sub    ($acc,$tmp);
-       &and    ($tp4,0xfefefefe);
-       &and    ($acc,0x1b1b1b1b);
-        &xor   ($tp2,$s[$i]);  # tp2^tp1
-       &xor    ($tp4,$acc);
-       &mov    ($tmp,0x80808080);
-
-       &and    ($tmp,$tp4);
-       &mov    ($acc,$tmp);
-       &shr    ($tmp,7);
-       &lea    ($tp8,&DWP(0,$tp4,$tp4));
-       &sub    ($acc,$tmp);
-       &and    ($tp8,0xfefefefe);
-       &and    ($acc,0x1b1b1b1b);
-        &xor   ($tp4,$s[$i]);  # tp4^tp1
-        &rotl  ($s[$i],8);     # = ROTATE(tp1,8)
-       &xor    ($tp8,$acc);
-
-       &xor    ($s[$i],$tp2);
-       &xor    ($tp2,$tp8);
-       &xor    ($s[$i],$tp4);
-       &xor    ($tp4,$tp8);
-       &rotl   ($tp2,24);
-       &xor    ($s[$i],$tp8);  # ^= tp8^(tp4^tp1)^(tp2^tp1)
-       &rotl   ($tp4,16);
-       &xor    ($s[$i],$tp2);  # ^= ROTATE(tp8^tp2^tp1,24)
-       &rotl   ($tp8,8);
-       &xor    ($s[$i],$tp4);  # ^= ROTATE(tp8^tp4^tp1,16)
-        &mov   ($s[0],$__s0)                   if($i==2); #prefetch $s0
-        &mov   ($s[1],$__s1)                   if($i==3); #prefetch $s1
-        &mov   ($s[2],$__s2)                   if($i==1);
-       &xor    ($s[$i],$tp8);  # ^= ROTATE(tp8,8)
-
-       &mov    ($s[3],$__s3)                   if($i==1);
-       &mov    (&DWP(4+4*$i,"esp"),$s[$i])     if($i>=2);
-}
-
-&function_begin_B("_x86_AES_decrypt_compact");
-       # note that caller is expected to allocate stack frame for me!
-       &mov    ($__key,$key);                  # save key
-
-       &xor    ($s0,&DWP(0,$key));             # xor with key
-       &xor    ($s1,&DWP(4,$key));
-       &xor    ($s2,&DWP(8,$key));
-       &xor    ($s3,&DWP(12,$key));
-
-       &mov    ($acc,&DWP(240,$key));          # load key->rounds
-
-       &lea    ($acc,&DWP(-2,$acc,$acc));
-       &lea    ($acc,&DWP(0,$key,$acc,8));
-       &mov    ($__end,$acc);                  # end of key schedule
-
-       # prefetch Td4
-       &mov    ($key,&DWP(0-128,$tbl));
-       &mov    ($acc,&DWP(32-128,$tbl));
-       &mov    ($key,&DWP(64-128,$tbl));
-       &mov    ($acc,&DWP(96-128,$tbl));
-       &mov    ($key,&DWP(128-128,$tbl));
-       &mov    ($acc,&DWP(160-128,$tbl));
-       &mov    ($key,&DWP(192-128,$tbl));
-       &mov    ($acc,&DWP(224-128,$tbl));
-
-       &set_label("loop",16);
-
-               &deccompact(0,$tbl,$s0,$s3,$s2,$s1,1);
-               &deccompact(1,$tbl,$s1,$s0,$s3,$s2,1);
-               &deccompact(2,$tbl,$s2,$s1,$s0,$s3,1);
-               &deccompact(3,$tbl,$s3,$s2,$s1,$s0,1);
-               &dectransform(2);
-               &dectransform(3);
-               &dectransform(0);
-               &dectransform(1);
-               &mov    ($key,$__key);
-               &mov    ($tbl,$__tbl);
-               &add    ($key,16);              # advance rd_key
-               &xor    ($s0,&DWP(0,$key));
-               &xor    ($s1,&DWP(4,$key));
-               &xor    ($s2,&DWP(8,$key));
-               &xor    ($s3,&DWP(12,$key));
-
-       &cmp    ($key,$__end);
-       &mov    ($__key,$key);
-       &jb     (&label("loop"));
-
-       &deccompact(0,$tbl,$s0,$s3,$s2,$s1);
-       &deccompact(1,$tbl,$s1,$s0,$s3,$s2);
-       &deccompact(2,$tbl,$s2,$s1,$s0,$s3);
-       &deccompact(3,$tbl,$s3,$s2,$s1,$s0);
-
-       &xor    ($s0,&DWP(16,$key));
-       &xor    ($s1,&DWP(20,$key));
-       &xor    ($s2,&DWP(24,$key));
-       &xor    ($s3,&DWP(28,$key));
-
-       &ret    ();
-&function_end_B("_x86_AES_decrypt_compact");
-
-######################################################################
-# "Compact" SSE block function.
-######################################################################
-
-sub sse_deccompact()
-{
-       &pshufw ("mm1","mm0",0x0c);             #  7, 6, 1, 0
-       &pshufw ("mm5","mm4",0x09);             # 13,12,11,10
-       &movd   ("eax","mm1");                  #  7, 6, 1, 0
-       &movd   ("ebx","mm5");                  # 13,12,11,10
-       &mov    ($__key,$key);
-
-       &movz   ($acc,&LB("eax"));              #  0
-       &movz   ("edx",&HB("eax"));             #  1
-       &pshufw ("mm2","mm0",0x06);             #  3, 2, 5, 4
-       &movz   ("ecx",&BP(-128,$tbl,$acc,1));  #  0
-       &movz   ($key,&LB("ebx"));              # 10
-       &movz   ("edx",&BP(-128,$tbl,"edx",1)); #  1
-       &shr    ("eax",16);                     #  7, 6
-       &shl    ("edx",8);                      #  1
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   # 10
-       &movz   ($key,&HB("ebx"));              # 11
-       &shl    ($acc,16);                      # 10
-       &pshufw ("mm6","mm4",0x03);             # 9, 8,15,14
-       &or     ("ecx",$acc);                   # 10
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   # 11
-       &movz   ($key,&HB("eax"));              #  7
-       &shl    ($acc,24);                      # 11
-       &shr    ("ebx",16);                     # 13,12
-       &or     ("edx",$acc);                   # 11
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  7
-       &movz   ($key,&HB("ebx"));              # 13
-       &shl    ($acc,24);                      #  7
-       &or     ("ecx",$acc);                   #  7
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   # 13
-       &movz   ($key,&LB("eax"));              #  6
-       &shl    ($acc,8);                       # 13
-       &movd   ("eax","mm2");                  #  3, 2, 5, 4
-       &or     ("ecx",$acc);                   # 13
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  6
-       &movz   ($key,&LB("ebx"));              # 12
-       &shl    ($acc,16);                      #  6
-       &movd   ("ebx","mm6");                  #  9, 8,15,14
-       &movd   ("mm0","ecx");                  # t[0] collected
-       &movz   ("ecx",&BP(-128,$tbl,$key,1));  # 12
-       &movz   ($key,&LB("eax"));              #  4
-       &or     ("ecx",$acc);                   # 12
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  4
-       &movz   ($key,&LB("ebx"));              # 14
-       &or     ("edx",$acc);                   #  4
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   # 14
-       &movz   ($key,&HB("eax"));              #  5
-       &shl    ($acc,16);                      # 14
-       &shr    ("eax",16);                     #  3, 2
-       &or     ("edx",$acc);                   # 14
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  5
-       &movz   ($key,&HB("ebx"));              # 15
-       &shr    ("ebx",16);                     #  9, 8
-       &shl    ($acc,8);                       #  5
-       &movd   ("mm1","edx");                  # t[1] collected
-       &movz   ("edx",&BP(-128,$tbl,$key,1));  # 15
-       &movz   ($key,&HB("ebx"));              #  9
-       &shl    ("edx",24);                     # 15
-       &and    ("ebx",0xff);                   #  8
-       &or     ("edx",$acc);                   # 15
-
-       &punpckldq      ("mm0","mm1");          # t[0,1] collected
-
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  9
-       &movz   ($key,&LB("eax"));              #  2
-       &shl    ($acc,8);                       #  9
-       &movz   ("eax",&HB("eax"));             #  3
-       &movz   ("ebx",&BP(-128,$tbl,"ebx",1)); #  8
-       &or     ("ecx",$acc);                   #  9
-       &movz   ($acc,&BP(-128,$tbl,$key,1));   #  2
-       &or     ("edx","ebx");                  #  8
-       &shl    ($acc,16);                      #  2
-       &movz   ("eax",&BP(-128,$tbl,"eax",1)); #  3
-       &or     ("edx",$acc);                   #  2
-       &shl    ("eax",24);                     #  3
-       &or     ("ecx","eax");                  #  3
-       &mov    ($key,$__key);
-       &movd   ("mm4","edx");                  # t[2] collected
-       &movd   ("mm5","ecx");                  # t[3] collected
-
-       &punpckldq      ("mm4","mm5");          # t[2,3] collected
-}
-
-                                       if (!$x86only) {
-&function_begin_B("_sse_AES_decrypt_compact");
-       &pxor   ("mm0",&QWP(0,$key));   #  7, 6, 5, 4, 3, 2, 1, 0
-       &pxor   ("mm4",&QWP(8,$key));   # 15,14,13,12,11,10, 9, 8
-
-       # note that caller is expected to allocate stack frame for me!
-       &mov    ($acc,&DWP(240,$key));          # load key->rounds
-       &lea    ($acc,&DWP(-2,$acc,$acc));
-       &lea    ($acc,&DWP(0,$key,$acc,8));
-       &mov    ($__end,$acc);                  # end of key schedule
-
-       &mov    ($s0,0x1b1b1b1b);               # magic constant
-       &mov    (&DWP(8,"esp"),$s0);
-       &mov    (&DWP(12,"esp"),$s0);
-
-       # prefetch Td4
-       &mov    ($s0,&DWP(0-128,$tbl));
-       &mov    ($s1,&DWP(32-128,$tbl));
-       &mov    ($s2,&DWP(64-128,$tbl));
-       &mov    ($s3,&DWP(96-128,$tbl));
-       &mov    ($s0,&DWP(128-128,$tbl));
-       &mov    ($s1,&DWP(160-128,$tbl));
-       &mov    ($s2,&DWP(192-128,$tbl));
-       &mov    ($s3,&DWP(224-128,$tbl));
-
-       &set_label("loop",16);
-               &sse_deccompact();
-               &add    ($key,16);
-               &cmp    ($key,$__end);
-               &ja     (&label("out"));
-
-               # ROTATE(x^y,N) == ROTATE(x,N)^ROTATE(y,N)
-               &movq   ("mm3","mm0");          &movq   ("mm7","mm4");
-               &movq   ("mm2","mm0",1);        &movq   ("mm6","mm4",1);
-               &movq   ("mm1","mm0");          &movq   ("mm5","mm4");
-               &pshufw ("mm0","mm0",0xb1);     &pshufw ("mm4","mm4",0xb1);# = ROTATE(tp0,16)
-               &pslld  ("mm2",8);              &pslld  ("mm6",8);
-               &psrld  ("mm3",8);              &psrld  ("mm7",8);
-               &pxor   ("mm0","mm2");          &pxor   ("mm4","mm6");  # ^= tp0<<8
-               &pxor   ("mm0","mm3");          &pxor   ("mm4","mm7");  # ^= tp0>>8
-               &pslld  ("mm2",16);             &pslld  ("mm6",16);
-               &psrld  ("mm3",16);             &psrld  ("mm7",16);
-               &pxor   ("mm0","mm2");          &pxor   ("mm4","mm6");  # ^= tp0<<24
-               &pxor   ("mm0","mm3");          &pxor   ("mm4","mm7");  # ^= tp0>>24
-
-               &movq   ("mm3",&QWP(8,"esp"));
-               &pxor   ("mm2","mm2");          &pxor   ("mm6","mm6");
-               &pcmpgtb("mm2","mm1");          &pcmpgtb("mm6","mm5");
-               &pand   ("mm2","mm3");          &pand   ("mm6","mm3");
-               &paddb  ("mm1","mm1");          &paddb  ("mm5","mm5");
-               &pxor   ("mm1","mm2");          &pxor   ("mm5","mm6");  # tp2
-               &movq   ("mm3","mm1");          &movq   ("mm7","mm5");
-               &movq   ("mm2","mm1");          &movq   ("mm6","mm5");
-               &pxor   ("mm0","mm1");          &pxor   ("mm4","mm5");  # ^= tp2
-               &pslld  ("mm3",24);             &pslld  ("mm7",24);
-               &psrld  ("mm2",8);              &psrld  ("mm6",8);
-               &pxor   ("mm0","mm3");          &pxor   ("mm4","mm7");  # ^= tp2<<24
-               &pxor   ("mm0","mm2");          &pxor   ("mm4","mm6");  # ^= tp2>>8
-
-               &movq   ("mm2",&QWP(8,"esp"));
-               &pxor   ("mm3","mm3");          &pxor   ("mm7","mm7");
-               &pcmpgtb("mm3","mm1");          &pcmpgtb("mm7","mm5");
-               &pand   ("mm3","mm2");          &pand   ("mm7","mm2");
-               &paddb  ("mm1","mm1");          &paddb  ("mm5","mm5");
-               &pxor   ("mm1","mm3");          &pxor   ("mm5","mm7");  # tp4
-               &pshufw ("mm3","mm1",0xb1);     &pshufw ("mm7","mm5",0xb1);
-               &pxor   ("mm0","mm1");          &pxor   ("mm4","mm5");  # ^= tp4
-               &pxor   ("mm0","mm3");          &pxor   ("mm4","mm7");  # ^= ROTATE(tp4,16)
-
-               &pxor   ("mm3","mm3");          &pxor   ("mm7","mm7");
-               &pcmpgtb("mm3","mm1");          &pcmpgtb("mm7","mm5");
-               &pand   ("mm3","mm2");          &pand   ("mm7","mm2");
-               &paddb  ("mm1","mm1");          &paddb  ("mm5","mm5");
-               &pxor   ("mm1","mm3");          &pxor   ("mm5","mm7");  # tp8
-               &pxor   ("mm0","mm1");          &pxor   ("mm4","mm5");  # ^= tp8
-               &movq   ("mm3","mm1");          &movq   ("mm7","mm5");
-               &pshufw ("mm2","mm1",0xb1);     &pshufw ("mm6","mm5",0xb1);
-               &pxor   ("mm0","mm2");          &pxor   ("mm4","mm6");  # ^= ROTATE(tp8,16)
-               &pslld  ("mm1",8);              &pslld  ("mm5",8);
-               &psrld  ("mm3",8);              &psrld  ("mm7",8);
-               &movq   ("mm2",&QWP(0,$key));   &movq   ("mm6",&QWP(8,$key));
-               &pxor   ("mm0","mm1");          &pxor   ("mm4","mm5");  # ^= tp8<<8
-               &pxor   ("mm0","mm3");          &pxor   ("mm4","mm7");  # ^= tp8>>8
-               &mov    ($s0,&DWP(0-128,$tbl));
-               &pslld  ("mm1",16);             &pslld  ("mm5",16);
-               &mov    ($s1,&DWP(64-128,$tbl));
-               &psrld  ("mm3",16);             &psrld  ("mm7",16);
-               &mov    ($s2,&DWP(128-128,$tbl));
-               &pxor   ("mm0","mm1");          &pxor   ("mm4","mm5");  # ^= tp8<<24
-               &mov    ($s3,&DWP(192-128,$tbl));
-               &pxor   ("mm0","mm3");          &pxor   ("mm4","mm7");  # ^= tp8>>24
-
-               &pxor   ("mm0","mm2");          &pxor   ("mm4","mm6");
-       &jmp    (&label("loop"));
-
-       &set_label("out",16);
-       &pxor   ("mm0",&QWP(0,$key));
-       &pxor   ("mm4",&QWP(8,$key));
-
-       &ret    ();
-&function_end_B("_sse_AES_decrypt_compact");
-                                       }
-
-######################################################################
-# Vanilla block function.
-######################################################################
-
-sub decstep()
-{ my ($i,$td,@s) = @_;
-  my $tmp = $key;
-  my $out = $i==3?$s[0]:$acc;
-
-       # no instructions are reordered, as performance appears
-       # optimal... or rather that all attempts to reorder didn't
-       # result in better performance [which by the way is not a
-       # bit lower than encryption].
-       if($i==3)   {   &mov    ($key,$__key);                  }
-       else        {   &mov    ($out,$s[0]);                   }
-                       &and    ($out,0xFF);
-                       &mov    ($out,&DWP(0,$td,$out,8));
-
-       if ($i==3)  {   $tmp=$s[1];                             }
-                       &movz   ($tmp,&HB($s[1]));
-                       &xor    ($out,&DWP(3,$td,$tmp,8));
-
-       if ($i==3)  {   $tmp=$s[2]; &mov ($s[1],$acc);          }
-       else        {   &mov    ($tmp,$s[2]);                   }
-                       &shr    ($tmp,16);
-                       &and    ($tmp,0xFF);
-                       &xor    ($out,&DWP(2,$td,$tmp,8));
-
-       if ($i==3)  {   $tmp=$s[3]; &mov ($s[2],$__s1);         }
-       else        {   &mov    ($tmp,$s[3]);                   }
-                       &shr    ($tmp,24);
-                       &xor    ($out,&DWP(1,$td,$tmp,8));
-       if ($i<2)   {   &mov    (&DWP(4+4*$i,"esp"),$out);      }
-       if ($i==3)  {   &mov    ($s[3],$__s0);                  }
-                       &comment();
-}
-
-sub declast()
-{ my ($i,$td,@s)=@_;
-  my $tmp = $key;
-  my $out = $i==3?$s[0]:$acc;
-
-       if($i==0)   {   &lea    ($td,&DWP(2048+128,$td));
-                       &mov    ($tmp,&DWP(0-128,$td));
-                       &mov    ($acc,&DWP(32-128,$td));
-                       &mov    ($tmp,&DWP(64-128,$td));
-                       &mov    ($acc,&DWP(96-128,$td));
-                       &mov    ($tmp,&DWP(128-128,$td));
-                       &mov    ($acc,&DWP(160-128,$td));
-                       &mov    ($tmp,&DWP(192-128,$td));
-                       &mov    ($acc,&DWP(224-128,$td));
-                       &lea    ($td,&DWP(-128,$td));           }
-       if($i==3)   {   &mov    ($key,$__key);                  }
-       else        {   &mov    ($out,$s[0]);                   }
-                       &and    ($out,0xFF);
-                       &movz   ($out,&BP(0,$td,$out,1));
-
-       if ($i==3)  {   $tmp=$s[1];                             }
-                       &movz   ($tmp,&HB($s[1]));
-                       &movz   ($tmp,&BP(0,$td,$tmp,1));
-                       &shl    ($tmp,8);
-                       &xor    ($out,$tmp);
-
-       if ($i==3)  {   $tmp=$s[2]; &mov ($s[1],$acc);          }
-       else        {   mov     ($tmp,$s[2]);                   }
-                       &shr    ($tmp,16);
-                       &and    ($tmp,0xFF);
-                       &movz   ($tmp,&BP(0,$td,$tmp,1));
-                       &shl    ($tmp,16);
-                       &xor    ($out,$tmp);
-
-       if ($i==3)  {   $tmp=$s[3]; &mov ($s[2],$__s1);         }
-       else        {   &mov    ($tmp,$s[3]);                   }
-                       &shr    ($tmp,24);
-                       &movz   ($tmp,&BP(0,$td,$tmp,1));
-                       &shl    ($tmp,24);
-                       &xor    ($out,$tmp);
-       if ($i<2)   {   &mov    (&DWP(4+4*$i,"esp"),$out);      }
-       if ($i==3)  {   &mov    ($s[3],$__s0);
-                       &lea    ($td,&DWP(-2048,$td));          }
-}
-
-&function_begin_B("_x86_AES_decrypt");
-       # note that caller is expected to allocate stack frame for me!
-       &mov    ($__key,$key);                  # save key
-
-       &xor    ($s0,&DWP(0,$key));             # xor with key
-       &xor    ($s1,&DWP(4,$key));
-       &xor    ($s2,&DWP(8,$key));
-       &xor    ($s3,&DWP(12,$key));
-
-       &mov    ($acc,&DWP(240,$key));          # load key->rounds
-
-       if ($small_footprint) {
-           &lea        ($acc,&DWP(-2,$acc,$acc));
-           &lea        ($acc,&DWP(0,$key,$acc,8));
-           &mov        ($__end,$acc);          # end of key schedule
-           &set_label("loop",16);
-               &decstep(0,$tbl,$s0,$s3,$s2,$s1);
-               &decstep(1,$tbl,$s1,$s0,$s3,$s2);
-               &decstep(2,$tbl,$s2,$s1,$s0,$s3);
-               &decstep(3,$tbl,$s3,$s2,$s1,$s0);
-               &add    ($key,16);              # advance rd_key
-               &xor    ($s0,&DWP(0,$key));
-               &xor    ($s1,&DWP(4,$key));
-               &xor    ($s2,&DWP(8,$key));
-               &xor    ($s3,&DWP(12,$key));
-           &cmp        ($key,$__end);
-           &mov        ($__key,$key);
-           &jb         (&label("loop"));
-       }
-       else {
-           &cmp        ($acc,10);
-           &jle        (&label("10rounds"));
-           &cmp        ($acc,12);
-           &jle        (&label("12rounds"));
-
-       &set_label("14rounds",4);
-           for ($i=1;$i<3;$i++) {
-               &decstep(0,$tbl,$s0,$s3,$s2,$s1);
-               &decstep(1,$tbl,$s1,$s0,$s3,$s2);
-               &decstep(2,$tbl,$s2,$s1,$s0,$s3);
-               &decstep(3,$tbl,$s3,$s2,$s1,$s0);
-               &xor    ($s0,&DWP(16*$i+0,$key));
-               &xor    ($s1,&DWP(16*$i+4,$key));
-               &xor    ($s2,&DWP(16*$i+8,$key));
-               &xor    ($s3,&DWP(16*$i+12,$key));
-           }
-           &add        ($key,32);
-           &mov        ($__key,$key);          # advance rd_key
-       &set_label("12rounds",4);
-           for ($i=1;$i<3;$i++) {
-               &decstep(0,$tbl,$s0,$s3,$s2,$s1);
-               &decstep(1,$tbl,$s1,$s0,$s3,$s2);
-               &decstep(2,$tbl,$s2,$s1,$s0,$s3);
-               &decstep(3,$tbl,$s3,$s2,$s1,$s0);
-               &xor    ($s0,&DWP(16*$i+0,$key));
-               &xor    ($s1,&DWP(16*$i+4,$key));
-               &xor    ($s2,&DWP(16*$i+8,$key));
-               &xor    ($s3,&DWP(16*$i+12,$key));
-           }
-           &add        ($key,32);
-           &mov        ($__key,$key);          # advance rd_key
-       &set_label("10rounds",4);
-           for ($i=1;$i<10;$i++) {
-               &decstep(0,$tbl,$s0,$s3,$s2,$s1);
-               &decstep(1,$tbl,$s1,$s0,$s3,$s2);
-               &decstep(2,$tbl,$s2,$s1,$s0,$s3);
-               &decstep(3,$tbl,$s3,$s2,$s1,$s0);
-               &xor    ($s0,&DWP(16*$i+0,$key));
-               &xor    ($s1,&DWP(16*$i+4,$key));
-               &xor    ($s2,&DWP(16*$i+8,$key));
-               &xor    ($s3,&DWP(16*$i+12,$key));
-           }
-       }
-
-       &declast(0,$tbl,$s0,$s3,$s2,$s1);
-       &declast(1,$tbl,$s1,$s0,$s3,$s2);
-       &declast(2,$tbl,$s2,$s1,$s0,$s3);
-       &declast(3,$tbl,$s3,$s2,$s1,$s0);
-
-       &add    ($key,$small_footprint?16:160);
-       &xor    ($s0,&DWP(0,$key));
-       &xor    ($s1,&DWP(4,$key));
-       &xor    ($s2,&DWP(8,$key));
-       &xor    ($s3,&DWP(12,$key));
-
-       &ret    ();
-
-&set_label("AES_Td",64);       # Yes! I keep it in the code segment!
-       &_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
-       &_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
-       &_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5);
-       &_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5);
-       &_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d);
-       &_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b);
-       &_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295);
-       &_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e);
-       &_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927);
-       &_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d);
-       &_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362);
-       &_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9);
-       &_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52);
-       &_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566);
-       &_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3);
-       &_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed);
-       &_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e);
-       &_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4);
-       &_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4);
-       &_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd);
-       &_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d);
-       &_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060);
-       &_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967);
-       &_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879);
-       &_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000);
-       &_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c);
-       &_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36);
-       &_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624);
-       &_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b);
-       &_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c);
-       &_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12);
-       &_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14);
-       &_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3);
-       &_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b);
-       &_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8);
-       &_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684);
-       &_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7);
-       &_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177);
-       &_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947);
-       &_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322);
-       &_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498);
-       &_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f);
-       &_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54);
-       &_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382);
-       &_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf);
-       &_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb);
-       &_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83);
-       &_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef);
-       &_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029);
-       &_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235);
-       &_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733);
-       &_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117);
-       &_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4);
-       &_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546);
-       &_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb);
-       &_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d);
-       &_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb);
-       &_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a);
-       &_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773);
-       &_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478);
-       &_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2);
-       &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
-       &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
-       &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
-
-#Td4:  # four copies of Td4 to choose from to avoid L1 aliasing
-       &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-       &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-       &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-       &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-       &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-       &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-       &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-       &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-       &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-       &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-       &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-       &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-       &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-       &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-       &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-       &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-       &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-       &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-       &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-       &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-       &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-       &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-       &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-       &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-       &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-       &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-       &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-       &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-       &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-       &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-       &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-       &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-
-       &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-       &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-       &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-       &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-       &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-       &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-       &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-       &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-       &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-       &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-       &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-       &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-       &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-       &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-       &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-       &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-       &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-       &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-       &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-       &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-       &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-       &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-       &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-       &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-       &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-       &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-       &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-       &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-       &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-       &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-       &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-       &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-
-       &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-       &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-       &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-       &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-       &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-       &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-       &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-       &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-       &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-       &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-       &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-       &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-       &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-       &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-       &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-       &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-       &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-       &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-       &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-       &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-       &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-       &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-       &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-       &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-       &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-       &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-       &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-       &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-       &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-       &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-       &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-       &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-
-       &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-       &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-       &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-       &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-       &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-       &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-       &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-       &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-       &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-       &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-       &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-       &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-       &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-       &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-       &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-       &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-       &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-       &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-       &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-       &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-       &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-       &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-       &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-       &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-       &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-       &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-       &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-       &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-       &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-       &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-       &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-       &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-&function_end_B("_x86_AES_decrypt");
-
-# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
-&function_begin("AES_decrypt");
-       &mov    ($acc,&wparam(0));              # load inp
-       &mov    ($key,&wparam(2));              # load key
-
-       &mov    ($s0,"esp");
-       &sub    ("esp",36);
-       &and    ("esp",-64);                    # align to cache-line
-
-       # place stack frame just "above" the key schedule
-       &lea    ($s1,&DWP(-64-63,$key));
-       &sub    ($s1,"esp");
-       &neg    ($s1);
-       &and    ($s1,0x3C0);    # modulo 1024, but aligned to cache-line
-       &sub    ("esp",$s1);
-       &add    ("esp",4);      # 4 is reserved for caller's return address
-       &mov    ($_esp,$s0);    # save stack pointer
-
-       &call   (&label("pic_point"));          # make it PIC!
-       &set_label("pic_point");
-       &blindpop($tbl);
-       &picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
-       &lea    ($tbl,&DWP(&label("AES_Td")."-".&label("pic_point"),$tbl));
-
-       # pick Td4 copy which can't "overlap" with stack frame or key schedule
-       &lea    ($s1,&DWP(768-4,"esp"));
-       &sub    ($s1,$tbl);
-       &and    ($s1,0x300);
-       &lea    ($tbl,&DWP(2048+128,$tbl,$s1));
-
-                                       if (!$x86only) {
-       &bt     (&DWP(0,$s0),25);       # check for SSE bit
-       &jnc    (&label("x86"));
-
-       &movq   ("mm0",&QWP(0,$acc));
-       &movq   ("mm4",&QWP(8,$acc));
-       &call   ("_sse_AES_decrypt_compact");
-       &mov    ("esp",$_esp);                  # restore stack pointer
-       &mov    ($acc,&wparam(1));              # load out
-       &movq   (&QWP(0,$acc),"mm0");           # write output data
-       &movq   (&QWP(8,$acc),"mm4");
-       &emms   ();
-       &function_end_A();
-                                       }
-       &set_label("x86",16);
-       &mov    ($_tbl,$tbl);
-       &mov    ($s0,&DWP(0,$acc));             # load input data
-       &mov    ($s1,&DWP(4,$acc));
-       &mov    ($s2,&DWP(8,$acc));
-       &mov    ($s3,&DWP(12,$acc));
-       &call   ("_x86_AES_decrypt_compact");
-       &mov    ("esp",$_esp);                  # restore stack pointer
-       &mov    ($acc,&wparam(1));              # load out
-       &mov    (&DWP(0,$acc),$s0);             # write output data
-       &mov    (&DWP(4,$acc),$s1);
-       &mov    (&DWP(8,$acc),$s2);
-       &mov    (&DWP(12,$acc),$s3);
-&function_end("AES_decrypt");
-
-# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
-#                      size_t length, const AES_KEY *key,
-#                      unsigned char *ivp,const int enc);
-{
-# stack frame layout
-#             -4(%esp)         # return address         0(%esp)
-#              0(%esp)         # s0 backing store       4(%esp)
-#              4(%esp)         # s1 backing store       8(%esp)
-#              8(%esp)         # s2 backing store      12(%esp)
-#             12(%esp)         # s3 backing store      16(%esp)
-#             16(%esp)         # key backup            20(%esp)
-#             20(%esp)         # end of key schedule   24(%esp)
-#             24(%esp)         # %ebp backup           28(%esp)
-#             28(%esp)         # %esp backup
-my $_inp=&DWP(32,"esp");       # copy of wparam(0)
-my $_out=&DWP(36,"esp");       # copy of wparam(1)
-my $_len=&DWP(40,"esp");       # copy of wparam(2)
-my $_key=&DWP(44,"esp");       # copy of wparam(3)
-my $_ivp=&DWP(48,"esp");       # copy of wparam(4)
-my $_tmp=&DWP(52,"esp");       # volatile variable
-#
-my $ivec=&DWP(60,"esp");       # ivec[16]
-my $aes_key=&DWP(76,"esp");    # copy of aes_key
-my $mark=&DWP(76+240,"esp");   # copy of aes_key->rounds
-
-&function_begin("AES_cbc_encrypt");
-       &mov    ($s2 eq "ecx"? $s2 : "",&wparam(2));    # load len
-       &cmp    ($s2,0);
-       &je     (&label("drop_out"));
-
-       &call   (&label("pic_point"));          # make it PIC!
-       &set_label("pic_point");
-       &blindpop($tbl);
-       &picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
-
-       &cmp    (&wparam(5),0);
-       &lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
-       &jne    (&label("picked_te"));
-       &lea    ($tbl,&DWP(&label("AES_Td")."-".&label("AES_Te"),$tbl));
-       &set_label("picked_te");
-
-       # one can argue if this is required
-       &pushf  ();
-       &cld    ();
-
-       &cmp    ($s2,$speed_limit);
-       &jb     (&label("slow_way"));
-       &test   ($s2,15);
-       &jnz    (&label("slow_way"));
-                                       if (!$x86only) {
-       &bt     (&DWP(0,$s0),28);       # check for hyper-threading bit
-       &jc     (&label("slow_way"));
-                                       }
-       # pre-allocate aligned stack frame...
-       &lea    ($acc,&DWP(-80-244,"esp"));
-       &and    ($acc,-64);
-
-       # ... and make sure it doesn't alias with $tbl modulo 4096
-       &mov    ($s0,$tbl);
-       &lea    ($s1,&DWP(2048+256,$tbl));
-       &mov    ($s3,$acc);
-       &and    ($s0,0xfff);            # s = %ebp&0xfff
-       &and    ($s1,0xfff);            # e = (%ebp+2048+256)&0xfff
-       &and    ($s3,0xfff);            # p = %esp&0xfff
-
-       &cmp    ($s3,$s1);              # if (p>=e) %esp =- (p-e);
-       &jb     (&label("tbl_break_out"));
-       &sub    ($s3,$s1);
-       &sub    ($acc,$s3);
-       &jmp    (&label("tbl_ok"));
-       &set_label("tbl_break_out",4);  # else %esp -= (p-s)&0xfff + framesz;
-       &sub    ($s3,$s0);
-       &and    ($s3,0xfff);
-       &add    ($s3,384);
-       &sub    ($acc,$s3);
-       &set_label("tbl_ok",4);
-
-       &lea    ($s3,&wparam(0));       # obtain pointer to parameter block
-       &exch   ("esp",$acc);           # allocate stack frame
-       &add    ("esp",4);              # reserve for return address!
-       &mov    ($_tbl,$tbl);           # save %ebp
-       &mov    ($_esp,$acc);           # save %esp
-
-       &mov    ($s0,&DWP(0,$s3));      # load inp
-       &mov    ($s1,&DWP(4,$s3));      # load out
-       #&mov   ($s2,&DWP(8,$s3));      # load len
-       &mov    ($key,&DWP(12,$s3));    # load key
-       &mov    ($acc,&DWP(16,$s3));    # load ivp
-       &mov    ($s3,&DWP(20,$s3));     # load enc flag
-
-       &mov    ($_inp,$s0);            # save copy of inp
-       &mov    ($_out,$s1);            # save copy of out
-       &mov    ($_len,$s2);            # save copy of len
-       &mov    ($_key,$key);           # save copy of key
-       &mov    ($_ivp,$acc);           # save copy of ivp
-
-       &mov    ($mark,0);              # copy of aes_key->rounds = 0;
-       # do we copy key schedule to stack?
-       &mov    ($s1 eq "ebx" ? $s1 : "",$key);
-       &mov    ($s2 eq "ecx" ? $s2 : "",244/4);
-       &sub    ($s1,$tbl);
-       &mov    ("esi",$key);
-       &and    ($s1,0xfff);
-       &lea    ("edi",$aes_key);
-       &cmp    ($s1,2048+256);
-       &jb     (&label("do_copy"));
-       &cmp    ($s1,4096-244);
-       &jb     (&label("skip_copy"));
-       &set_label("do_copy",4);
-               &mov    ($_key,"edi");
-               &data_word(0xA5F3F689); # rep movsd
-       &set_label("skip_copy");
-
-       &mov    ($key,16);
-       &set_label("prefetch_tbl",4);
-               &mov    ($s0,&DWP(0,$tbl));
-               &mov    ($s1,&DWP(32,$tbl));
-               &mov    ($s2,&DWP(64,$tbl));
-               &mov    ($acc,&DWP(96,$tbl));
-               &lea    ($tbl,&DWP(128,$tbl));
-               &sub    ($key,1);
-       &jnz    (&label("prefetch_tbl"));
-       &sub    ($tbl,2048);
-
-       &mov    ($acc,$_inp);
-       &mov    ($key,$_ivp);
-
-       &cmp    ($s3,0);
-       &je     (&label("fast_decrypt"));
-
-#----------------------------- ENCRYPT -----------------------------#
-       &mov    ($s0,&DWP(0,$key));             # load iv
-       &mov    ($s1,&DWP(4,$key));
-
-       &set_label("fast_enc_loop",16);
-               &mov    ($s2,&DWP(8,$key));
-               &mov    ($s3,&DWP(12,$key));
-
-               &xor    ($s0,&DWP(0,$acc));     # xor input data
-               &xor    ($s1,&DWP(4,$acc));
-               &xor    ($s2,&DWP(8,$acc));
-               &xor    ($s3,&DWP(12,$acc));
-
-               &mov    ($key,$_key);           # load key
-               &call   ("_x86_AES_encrypt");
-
-               &mov    ($acc,$_inp);           # load inp
-               &mov    ($key,$_out);           # load out
-
-               &mov    (&DWP(0,$key),$s0);     # save output data
-               &mov    (&DWP(4,$key),$s1);
-               &mov    (&DWP(8,$key),$s2);
-               &mov    (&DWP(12,$key),$s3);
-
-               &lea    ($acc,&DWP(16,$acc));   # advance inp
-               &mov    ($s2,$_len);            # load len
-               &mov    ($_inp,$acc);           # save inp
-               &lea    ($s3,&DWP(16,$key));    # advance out
-               &mov    ($_out,$s3);            # save out
-               &sub    ($s2,16);               # decrease len
-               &mov    ($_len,$s2);            # save len
-       &jnz    (&label("fast_enc_loop"));
-       &mov    ($acc,$_ivp);           # load ivp
-       &mov    ($s2,&DWP(8,$key));     # restore last 2 dwords
-       &mov    ($s3,&DWP(12,$key));
-       &mov    (&DWP(0,$acc),$s0);     # save ivec
-       &mov    (&DWP(4,$acc),$s1);
-       &mov    (&DWP(8,$acc),$s2);
-       &mov    (&DWP(12,$acc),$s3);
-
-       &cmp    ($mark,0);              # was the key schedule copied?
-       &mov    ("edi",$_key);
-       &je     (&label("skip_ezero"));
-       # zero copy of key schedule
-       &mov    ("ecx",240/4);
-       &xor    ("eax","eax");
-       &align  (4);
-       &data_word(0xABF3F689);         # rep stosd
-       &set_label("skip_ezero");
-       &mov    ("esp",$_esp);
-       &popf   ();
-    &set_label("drop_out");
-       &function_end_A();
-       &pushf  ();                     # kludge, never executed
-
-#----------------------------- DECRYPT -----------------------------#
-&set_label("fast_decrypt",16);
-
-       &cmp    ($acc,$_out);
-       &je     (&label("fast_dec_in_place"));  # in-place processing...
-
-       &mov    ($_tmp,$key);
-
-       &align  (4);
-       &set_label("fast_dec_loop",16);
-               &mov    ($s0,&DWP(0,$acc));     # read input
-               &mov    ($s1,&DWP(4,$acc));
-               &mov    ($s2,&DWP(8,$acc));
-               &mov    ($s3,&DWP(12,$acc));
-
-               &mov    ($key,$_key);           # load key
-               &call   ("_x86_AES_decrypt");
-
-               &mov    ($key,$_tmp);           # load ivp
-               &mov    ($acc,$_len);           # load len
-               &xor    ($s0,&DWP(0,$key));     # xor iv
-               &xor    ($s1,&DWP(4,$key));
-               &xor    ($s2,&DWP(8,$key));
-               &xor    ($s3,&DWP(12,$key));
-
-               &mov    ($key,$_out);           # load out
-               &mov    ($acc,$_inp);           # load inp
-
-               &mov    (&DWP(0,$key),$s0);     # write output
-               &mov    (&DWP(4,$key),$s1);
-               &mov    (&DWP(8,$key),$s2);
-               &mov    (&DWP(12,$key),$s3);
-
-               &mov    ($s2,$_len);            # load len
-               &mov    ($_tmp,$acc);           # save ivp
-               &lea    ($acc,&DWP(16,$acc));   # advance inp
-               &mov    ($_inp,$acc);           # save inp
-               &lea    ($key,&DWP(16,$key));   # advance out
-               &mov    ($_out,$key);           # save out
-               &sub    ($s2,16);               # decrease len
-               &mov    ($_len,$s2);            # save len
-       &jnz    (&label("fast_dec_loop"));
-       &mov    ($key,$_tmp);           # load temp ivp
-       &mov    ($acc,$_ivp);           # load user ivp
-       &mov    ($s0,&DWP(0,$key));     # load iv
-       &mov    ($s1,&DWP(4,$key));
-       &mov    ($s2,&DWP(8,$key));
-       &mov    ($s3,&DWP(12,$key));
-       &mov    (&DWP(0,$acc),$s0);     # copy back to user
-       &mov    (&DWP(4,$acc),$s1);
-       &mov    (&DWP(8,$acc),$s2);
-       &mov    (&DWP(12,$acc),$s3);
-       &jmp    (&label("fast_dec_out"));
-
-    &set_label("fast_dec_in_place",16);
-       &set_label("fast_dec_in_place_loop");
-               &mov    ($s0,&DWP(0,$acc));     # read input
-               &mov    ($s1,&DWP(4,$acc));
-               &mov    ($s2,&DWP(8,$acc));
-               &mov    ($s3,&DWP(12,$acc));
-
-               &lea    ($key,$ivec);
-               &mov    (&DWP(0,$key),$s0);     # copy to temp
-               &mov    (&DWP(4,$key),$s1);
-               &mov    (&DWP(8,$key),$s2);
-               &mov    (&DWP(12,$key),$s3);
-
-               &mov    ($key,$_key);           # load key
-               &call   ("_x86_AES_decrypt");
-
-               &mov    ($key,$_ivp);           # load ivp
-               &mov    ($acc,$_out);           # load out
-               &xor    ($s0,&DWP(0,$key));     # xor iv
-               &xor    ($s1,&DWP(4,$key));
-               &xor    ($s2,&DWP(8,$key));
-               &xor    ($s3,&DWP(12,$key));
-
-               &mov    (&DWP(0,$acc),$s0);     # write output
-               &mov    (&DWP(4,$acc),$s1);
-               &mov    (&DWP(8,$acc),$s2);
-               &mov    (&DWP(12,$acc),$s3);
-
-               &lea    ($acc,&DWP(16,$acc));   # advance out
-               &mov    ($_out,$acc);           # save out
-
-               &lea    ($acc,$ivec);
-               &mov    ($s0,&DWP(0,$acc));     # read temp
-               &mov    ($s1,&DWP(4,$acc));
-               &mov    ($s2,&DWP(8,$acc));
-               &mov    ($s3,&DWP(12,$acc));
-
-               &mov    (&DWP(0,$key),$s0);     # copy iv
-               &mov    (&DWP(4,$key),$s1);
-               &mov    (&DWP(8,$key),$s2);
-               &mov    (&DWP(12,$key),$s3);
-
-               &mov    ($acc,$_inp);           # load inp
-               &mov    ($s2,$_len);            # load len
-               &lea    ($acc,&DWP(16,$acc));   # advance inp
-               &mov    ($_inp,$acc);           # save inp
-               &sub    ($s2,16);               # decrease len
-               &mov    ($_len,$s2);            # save len
-       &jnz    (&label("fast_dec_in_place_loop"));
-
-    &set_label("fast_dec_out",4);
-       &cmp    ($mark,0);              # was the key schedule copied?
-       &mov    ("edi",$_key);
-       &je     (&label("skip_dzero"));
-       # zero copy of key schedule
-       &mov    ("ecx",240/4);
-       &xor    ("eax","eax");
-       &align  (4);
-       &data_word(0xABF3F689);         # rep stosd
-       &set_label("skip_dzero");
-       &mov    ("esp",$_esp);
-       &popf   ();
-       &function_end_A();
-       &pushf  ();                     # kludge, never executed
-
-#--------------------------- SLOW ROUTINE ---------------------------#
-&set_label("slow_way",16);
-
-       &mov    ($s0,&DWP(0,$s0)) if (!$x86only);# load OPENSSL_ia32cap
-       &mov    ($key,&wparam(3));      # load key
-
-       # pre-allocate aligned stack frame...
-       &lea    ($acc,&DWP(-80,"esp"));
-       &and    ($acc,-64);
-
-       # ... and make sure it doesn't alias with $key modulo 1024
-       &lea    ($s1,&DWP(-80-63,$key));
-       &sub    ($s1,$acc);
-       &neg    ($s1);
-       &and    ($s1,0x3C0);    # modulo 1024, but aligned to cache-line
-       &sub    ($acc,$s1);
-
-       # pick S-box copy which can't overlap with stack frame or $key
-       &lea    ($s1,&DWP(768,$acc));
-       &sub    ($s1,$tbl);
-       &and    ($s1,0x300);
-       &lea    ($tbl,&DWP(2048+128,$tbl,$s1));
-
-       &lea    ($s3,&wparam(0));       # pointer to parameter block
-
-       &exch   ("esp",$acc);
-       &add    ("esp",4);              # reserve for return address!
-       &mov    ($_tbl,$tbl);           # save %ebp
-       &mov    ($_esp,$acc);           # save %esp
-       &mov    ($_tmp,$s0);            # save OPENSSL_ia32cap
-
-       &mov    ($s0,&DWP(0,$s3));      # load inp
-       &mov    ($s1,&DWP(4,$s3));      # load out
-       #&mov   ($s2,&DWP(8,$s3));      # load len
-       #&mov   ($key,&DWP(12,$s3));    # load key
-       &mov    ($acc,&DWP(16,$s3));    # load ivp
-       &mov    ($s3,&DWP(20,$s3));     # load enc flag
-
-       &mov    ($_inp,$s0);            # save copy of inp
-       &mov    ($_out,$s1);            # save copy of out
-       &mov    ($_len,$s2);            # save copy of len
-       &mov    ($_key,$key);           # save copy of key
-       &mov    ($_ivp,$acc);           # save copy of ivp
-
-       &mov    ($key,$acc);
-       &mov    ($acc,$s0);
-
-       &cmp    ($s3,0);
-       &je     (&label("slow_decrypt"));
-
-#--------------------------- SLOW ENCRYPT ---------------------------#
-       &cmp    ($s2,16);
-       &mov    ($s3,$s1);
-       &jb     (&label("slow_enc_tail"));
-
-                                       if (!$x86only) {
-       &bt     ($_tmp,25);             # check for SSE bit
-       &jnc    (&label("slow_enc_x86"));
-
-       &movq   ("mm0",&QWP(0,$key));   # load iv
-       &movq   ("mm4",&QWP(8,$key));
-
-       &set_label("slow_enc_loop_sse",16);
-               &pxor   ("mm0",&QWP(0,$acc));   # xor input data
-               &pxor   ("mm4",&QWP(8,$acc));
-
-               &mov    ($key,$_key);
-               &call   ("_sse_AES_encrypt_compact");
-
-               &mov    ($acc,$_inp);           # load inp
-               &mov    ($key,$_out);           # load out
-               &mov    ($s2,$_len);            # load len
-
-               &movq   (&QWP(0,$key),"mm0");   # save output data
-               &movq   (&QWP(8,$key),"mm4");
-
-               &lea    ($acc,&DWP(16,$acc));   # advance inp
-               &mov    ($_inp,$acc);           # save inp
-               &lea    ($s3,&DWP(16,$key));    # advance out
-               &mov    ($_out,$s3);            # save out
-               &sub    ($s2,16);               # decrease len
-               &cmp    ($s2,16);
-               &mov    ($_len,$s2);            # save len
-       &jae    (&label("slow_enc_loop_sse"));
-       &test   ($s2,15);
-       &jnz    (&label("slow_enc_tail"));
-       &mov    ($acc,$_ivp);           # load ivp
-       &movq   (&QWP(0,$acc),"mm0");   # save ivec
-       &movq   (&QWP(8,$acc),"mm4");
-       &emms   ();
-       &mov    ("esp",$_esp);
-       &popf   ();
-       &function_end_A();
-       &pushf  ();                     # kludge, never executed
-                                       }
-    &set_label("slow_enc_x86",16);
-       &mov    ($s0,&DWP(0,$key));     # load iv
-       &mov    ($s1,&DWP(4,$key));
-
-       &set_label("slow_enc_loop_x86",4);
-               &mov    ($s2,&DWP(8,$key));
-               &mov    ($s3,&DWP(12,$key));
-
-               &xor    ($s0,&DWP(0,$acc));     # xor input data
-               &xor    ($s1,&DWP(4,$acc));
-               &xor    ($s2,&DWP(8,$acc));
-               &xor    ($s3,&DWP(12,$acc));
-
-               &mov    ($key,$_key);           # load key
-               &call   ("_x86_AES_encrypt_compact");
-
-               &mov    ($acc,$_inp);           # load inp
-               &mov    ($key,$_out);           # load out
-
-               &mov    (&DWP(0,$key),$s0);     # save output data
-               &mov    (&DWP(4,$key),$s1);
-               &mov    (&DWP(8,$key),$s2);
-               &mov    (&DWP(12,$key),$s3);
-
-               &mov    ($s2,$_len);            # load len
-               &lea    ($acc,&DWP(16,$acc));   # advance inp
-               &mov    ($_inp,$acc);           # save inp
-               &lea    ($s3,&DWP(16,$key));    # advance out
-               &mov    ($_out,$s3);            # save out
-               &sub    ($s2,16);               # decrease len
-               &cmp    ($s2,16);
-               &mov    ($_len,$s2);            # save len
-       &jae    (&label("slow_enc_loop_x86"));
-       &test   ($s2,15);
-       &jnz    (&label("slow_enc_tail"));
-       &mov    ($acc,$_ivp);           # load ivp
-       &mov    ($s2,&DWP(8,$key));     # restore last dwords
-       &mov    ($s3,&DWP(12,$key));
-       &mov    (&DWP(0,$acc),$s0);     # save ivec
-       &mov    (&DWP(4,$acc),$s1);
-       &mov    (&DWP(8,$acc),$s2);
-       &mov    (&DWP(12,$acc),$s3);
-
-       &mov    ("esp",$_esp);
-       &popf   ();
-       &function_end_A();
-       &pushf  ();                     # kludge, never executed
-
-    &set_label("slow_enc_tail",16);
-       &emms   ()      if (!$x86only);
-       &mov    ($key eq "edi"? $key:"",$s3);   # load out to edi
-       &mov    ($s1,16);
-       &sub    ($s1,$s2);
-       &cmp    ($key,$acc eq "esi"? $acc:"");  # compare with inp
-       &je     (&label("enc_in_place"));
-       &align  (4);
-       &data_word(0xA4F3F689); # rep movsb     # copy input
-       &jmp    (&label("enc_skip_in_place"));
-    &set_label("enc_in_place");
-       &lea    ($key,&DWP(0,$key,$s2));
-    &set_label("enc_skip_in_place");
-       &mov    ($s2,$s1);
-       &xor    ($s0,$s0);
-       &align  (4);
-       &data_word(0xAAF3F689); # rep stosb     # zero tail
-
-       &mov    ($key,$_ivp);                   # restore ivp
-       &mov    ($acc,$s3);                     # output as input
-       &mov    ($s0,&DWP(0,$key));
-       &mov    ($s1,&DWP(4,$key));
-       &mov    ($_len,16);                     # len=16
-       &jmp    (&label("slow_enc_loop_x86"));  # one more spin...
-
-#--------------------------- SLOW DECRYPT ---------------------------#
-&set_label("slow_decrypt",16);
-                                       if (!$x86only) {
-       &bt     ($_tmp,25);             # check for SSE bit
-       &jnc    (&label("slow_dec_loop_x86"));
-
-       &set_label("slow_dec_loop_sse",4);
-               &movq   ("mm0",&QWP(0,$acc));   # read input
-               &movq   ("mm4",&QWP(8,$acc));
-
-               &mov    ($key,$_key);
-               &call   ("_sse_AES_decrypt_compact");
-
-               &mov    ($acc,$_inp);           # load inp
-               &lea    ($s0,$ivec);
-               &mov    ($s1,$_out);            # load out
-               &mov    ($s2,$_len);            # load len
-               &mov    ($key,$_ivp);           # load ivp
-
-               &movq   ("mm1",&QWP(0,$acc));   # re-read input
-               &movq   ("mm5",&QWP(8,$acc));
-
-               &pxor   ("mm0",&QWP(0,$key));   # xor iv
-               &pxor   ("mm4",&QWP(8,$key));
-
-               &movq   (&QWP(0,$key),"mm1");   # copy input to iv
-               &movq   (&QWP(8,$key),"mm5");
-
-               &sub    ($s2,16);               # decrease len
-               &jc     (&label("slow_dec_partial_sse"));
-
-               &movq   (&QWP(0,$s1),"mm0");    # write output
-               &movq   (&QWP(8,$s1),"mm4");
-
-               &lea    ($s1,&DWP(16,$s1));     # advance out
-               &mov    ($_out,$s1);            # save out
-               &lea    ($acc,&DWP(16,$acc));   # advance inp
-               &mov    ($_inp,$acc);           # save inp
-               &mov    ($_len,$s2);            # save len
-       &jnz    (&label("slow_dec_loop_sse"));
-       &emms   ();
-       &mov    ("esp",$_esp);
-       &popf   ();
-       &function_end_A();
-       &pushf  ();                     # kludge, never executed
-
-    &set_label("slow_dec_partial_sse",16);
-       &movq   (&QWP(0,$s0),"mm0");    # save output to temp
-       &movq   (&QWP(8,$s0),"mm4");
-       &emms   ();
-
-       &add    ($s2 eq "ecx" ? "ecx":"",16);
-       &mov    ("edi",$s1);            # out
-       &mov    ("esi",$s0);            # temp
-       &align  (4);
-       &data_word(0xA4F3F689);         # rep movsb # copy partial output
-
-       &mov    ("esp",$_esp);
-       &popf   ();
-       &function_end_A();
-       &pushf  ();                     # kludge, never executed
-                                       }
-       &set_label("slow_dec_loop_x86",16);
-               &mov    ($s0,&DWP(0,$acc));     # read input
-               &mov    ($s1,&DWP(4,$acc));
-               &mov    ($s2,&DWP(8,$acc));
-               &mov    ($s3,&DWP(12,$acc));
-
-               &lea    ($key,$ivec);
-               &mov    (&DWP(0,$key),$s0);     # copy to temp
-               &mov    (&DWP(4,$key),$s1);
-               &mov    (&DWP(8,$key),$s2);
-               &mov    (&DWP(12,$key),$s3);
-
-               &mov    ($key,$_key);           # load key
-               &call   ("_x86_AES_decrypt_compact");
-
-               &mov    ($key,$_ivp);           # load ivp
-               &mov    ($acc,$_len);           # load len
-               &xor    ($s0,&DWP(0,$key));     # xor iv
-               &xor    ($s1,&DWP(4,$key));
-               &xor    ($s2,&DWP(8,$key));
-               &xor    ($s3,&DWP(12,$key));
-
-               &sub    ($acc,16);
-               &jc     (&label("slow_dec_partial_x86"));
-
-               &mov    ($_len,$acc);           # save len
-               &mov    ($acc,$_out);           # load out
-
-               &mov    (&DWP(0,$acc),$s0);     # write output
-               &mov    (&DWP(4,$acc),$s1);
-               &mov    (&DWP(8,$acc),$s2);
-               &mov    (&DWP(12,$acc),$s3);
-
-               &lea    ($acc,&DWP(16,$acc));   # advance out
-               &mov    ($_out,$acc);           # save out
-
-               &lea    ($acc,$ivec);
-               &mov    ($s0,&DWP(0,$acc));     # read temp
-               &mov    ($s1,&DWP(4,$acc));
-               &mov    ($s2,&DWP(8,$acc));
-               &mov    ($s3,&DWP(12,$acc));
-
-               &mov    (&DWP(0,$key),$s0);     # copy it to iv
-               &mov    (&DWP(4,$key),$s1);
-               &mov    (&DWP(8,$key),$s2);
-               &mov    (&DWP(12,$key),$s3);
-
-               &mov    ($acc,$_inp);           # load inp
-               &lea    ($acc,&DWP(16,$acc));   # advance inp
-               &mov    ($_inp,$acc);           # save inp
-       &jnz    (&label("slow_dec_loop_x86"));
-       &mov    ("esp",$_esp);
-       &popf   ();
-       &function_end_A();
-       &pushf  ();                     # kludge, never executed
-
-    &set_label("slow_dec_partial_x86",16);
-       &lea    ($acc,$ivec);
-       &mov    (&DWP(0,$acc),$s0);     # save output to temp
-       &mov    (&DWP(4,$acc),$s1);
-       &mov    (&DWP(8,$acc),$s2);
-       &mov    (&DWP(12,$acc),$s3);
-
-       &mov    ($acc,$_inp);
-       &mov    ($s0,&DWP(0,$acc));     # re-read input
-       &mov    ($s1,&DWP(4,$acc));
-       &mov    ($s2,&DWP(8,$acc));
-       &mov    ($s3,&DWP(12,$acc));
-
-       &mov    (&DWP(0,$key),$s0);     # copy it to iv
-       &mov    (&DWP(4,$key),$s1);
-       &mov    (&DWP(8,$key),$s2);
-       &mov    (&DWP(12,$key),$s3);
-
-       &mov    ("ecx",$_len);
-       &mov    ("edi",$_out);
-       &lea    ("esi",$ivec);
-       &align  (4);
-       &data_word(0xA4F3F689);         # rep movsb # copy partial output
-
-       &mov    ("esp",$_esp);
-       &popf   ();
-&function_end("AES_cbc_encrypt");
-}
-
-#------------------------------------------------------------------#
-
-sub enckey()
-{
-       &movz   ("esi",&LB("edx"));             # rk[i]>>0
-       &movz   ("ebx",&BP(-128,$tbl,"esi",1));
-       &movz   ("esi",&HB("edx"));             # rk[i]>>8
-       &shl    ("ebx",24);
-       &xor    ("eax","ebx");
-
-       &movz   ("ebx",&BP(-128,$tbl,"esi",1));
-       &shr    ("edx",16);
-       &movz   ("esi",&LB("edx"));             # rk[i]>>16
-       &xor    ("eax","ebx");
-
-       &movz   ("ebx",&BP(-128,$tbl,"esi",1));
-       &movz   ("esi",&HB("edx"));             # rk[i]>>24
-       &shl    ("ebx",8);
-       &xor    ("eax","ebx");
-
-       &movz   ("ebx",&BP(-128,$tbl,"esi",1));
-       &shl    ("ebx",16);
-       &xor    ("eax","ebx");
-
-       &xor    ("eax",&DWP(1024-128,$tbl,"ecx",4));    # rcon
-}
-
-&function_begin("_x86_AES_set_encrypt_key");
-       &mov    ("esi",&wparam(1));             # user supplied key
-       &mov    ("edi",&wparam(3));             # private key schedule
-
-       &test   ("esi",-1);
-       &jz     (&label("badpointer"));
-       &test   ("edi",-1);
-       &jz     (&label("badpointer"));
-
-       &call   (&label("pic_point"));
-       &set_label("pic_point");
-       &blindpop($tbl);
-       &lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
-       &lea    ($tbl,&DWP(2048+128,$tbl));
-
-       # prefetch Te4
-       &mov    ("eax",&DWP(0-128,$tbl));
-       &mov    ("ebx",&DWP(32-128,$tbl));
-       &mov    ("ecx",&DWP(64-128,$tbl));
-       &mov    ("edx",&DWP(96-128,$tbl));
-       &mov    ("eax",&DWP(128-128,$tbl));
-       &mov    ("ebx",&DWP(160-128,$tbl));
-       &mov    ("ecx",&DWP(192-128,$tbl));
-       &mov    ("edx",&DWP(224-128,$tbl));
-
-       &mov    ("ecx",&wparam(2));             # number of bits in key
-       &cmp    ("ecx",128);
-       &je     (&label("10rounds"));
-       &cmp    ("ecx",192);
-       &je     (&label("12rounds"));
-       &cmp    ("ecx",256);
-       &je     (&label("14rounds"));
-       &mov    ("eax",-2);                     # invalid number of bits
-       &jmp    (&label("exit"));
-
-    &set_label("10rounds");
-       &mov    ("eax",&DWP(0,"esi"));          # copy first 4 dwords
-       &mov    ("ebx",&DWP(4,"esi"));
-       &mov    ("ecx",&DWP(8,"esi"));
-       &mov    ("edx",&DWP(12,"esi"));
-       &mov    (&DWP(0,"edi"),"eax");
-       &mov    (&DWP(4,"edi"),"ebx");
-       &mov    (&DWP(8,"edi"),"ecx");
-       &mov    (&DWP(12,"edi"),"edx");
-
-       &xor    ("ecx","ecx");
-       &jmp    (&label("10shortcut"));
-
-       &align  (4);
-       &set_label("10loop");
-               &mov    ("eax",&DWP(0,"edi"));          # rk[0]
-               &mov    ("edx",&DWP(12,"edi"));         # rk[3]
-       &set_label("10shortcut");
-               &enckey ();
-
-               &mov    (&DWP(16,"edi"),"eax");         # rk[4]
-               &xor    ("eax",&DWP(4,"edi"));
-               &mov    (&DWP(20,"edi"),"eax");         # rk[5]
-               &xor    ("eax",&DWP(8,"edi"));
-               &mov    (&DWP(24,"edi"),"eax");         # rk[6]
-               &xor    ("eax",&DWP(12,"edi"));
-               &mov    (&DWP(28,"edi"),"eax");         # rk[7]
-               &inc    ("ecx");
-               &add    ("edi",16);
-               &cmp    ("ecx",10);
-       &jl     (&label("10loop"));
-
-       &mov    (&DWP(80,"edi"),10);            # setup number of rounds
-       &xor    ("eax","eax");
-       &jmp    (&label("exit"));
-
-    &set_label("12rounds");
-       &mov    ("eax",&DWP(0,"esi"));          # copy first 6 dwords
-       &mov    ("ebx",&DWP(4,"esi"));
-       &mov    ("ecx",&DWP(8,"esi"));
-       &mov    ("edx",&DWP(12,"esi"));
-       &mov    (&DWP(0,"edi"),"eax");
-       &mov    (&DWP(4,"edi"),"ebx");
-       &mov    (&DWP(8,"edi"),"ecx");
-       &mov    (&DWP(12,"edi"),"edx");
-       &mov    ("ecx",&DWP(16,"esi"));
-       &mov    ("edx",&DWP(20,"esi"));
-       &mov    (&DWP(16,"edi"),"ecx");
-       &mov    (&DWP(20,"edi"),"edx");
-
-       &xor    ("ecx","ecx");
-       &jmp    (&label("12shortcut"));
-
-       &align  (4);
-       &set_label("12loop");
-               &mov    ("eax",&DWP(0,"edi"));          # rk[0]
-               &mov    ("edx",&DWP(20,"edi"));         # rk[5]
-       &set_label("12shortcut");
-               &enckey ();
-
-               &mov    (&DWP(24,"edi"),"eax");         # rk[6]
-               &xor    ("eax",&DWP(4,"edi"));
-               &mov    (&DWP(28,"edi"),"eax");         # rk[7]
-               &xor    ("eax",&DWP(8,"edi"));
-               &mov    (&DWP(32,"edi"),"eax");         # rk[8]
-               &xor    ("eax",&DWP(12,"edi"));
-               &mov    (&DWP(36,"edi"),"eax");         # rk[9]
-
-               &cmp    ("ecx",7);
-               &je     (&label("12break"));
-               &inc    ("ecx");
-
-               &xor    ("eax",&DWP(16,"edi"));
-               &mov    (&DWP(40,"edi"),"eax");         # rk[10]
-               &xor    ("eax",&DWP(20,"edi"));
-               &mov    (&DWP(44,"edi"),"eax");         # rk[11]
-
-               &add    ("edi",24);
-       &jmp    (&label("12loop"));
-
-       &set_label("12break");
-       &mov    (&DWP(72,"edi"),12);            # setup number of rounds
-       &xor    ("eax","eax");
-       &jmp    (&label("exit"));
-
-    &set_label("14rounds");
-       &mov    ("eax",&DWP(0,"esi"));          # copy first 8 dwords
-       &mov    ("ebx",&DWP(4,"esi"));
-       &mov    ("ecx",&DWP(8,"esi"));
-       &mov    ("edx",&DWP(12,"esi"));
-       &mov    (&DWP(0,"edi"),"eax");
-       &mov    (&DWP(4,"edi"),"ebx");
-       &mov    (&DWP(8,"edi"),"ecx");
-       &mov    (&DWP(12,"edi"),"edx");
-       &mov    ("eax",&DWP(16,"esi"));
-       &mov    ("ebx",&DWP(20,"esi"));
-       &mov    ("ecx",&DWP(24,"esi"));
-       &mov    ("edx",&DWP(28,"esi"));
-       &mov    (&DWP(16,"edi"),"eax");
-       &mov    (&DWP(20,"edi"),"ebx");
-       &mov    (&DWP(24,"edi"),"ecx");
-       &mov    (&DWP(28,"edi"),"edx");
-
-       &xor    ("ecx","ecx");
-       &jmp    (&label("14shortcut"));
-
-       &align  (4);
-       &set_label("14loop");
-               &mov    ("edx",&DWP(28,"edi"));         # rk[7]
-       &set_label("14shortcut");
-               &mov    ("eax",&DWP(0,"edi"));          # rk[0]
-
-               &enckey ();
-
-               &mov    (&DWP(32,"edi"),"eax");         # rk[8]
-               &xor    ("eax",&DWP(4,"edi"));
-               &mov    (&DWP(36,"edi"),"eax");         # rk[9]
-               &xor    ("eax",&DWP(8,"edi"));
-               &mov    (&DWP(40,"edi"),"eax");         # rk[10]
-               &xor    ("eax",&DWP(12,"edi"));
-               &mov    (&DWP(44,"edi"),"eax");         # rk[11]
-
-               &cmp    ("ecx",6);
-               &je     (&label("14break"));
-               &inc    ("ecx");
-
-               &mov    ("edx","eax");
-               &mov    ("eax",&DWP(16,"edi"));         # rk[4]
-               &movz   ("esi",&LB("edx"));             # rk[11]>>0
-               &movz   ("ebx",&BP(-128,$tbl,"esi",1));
-               &movz   ("esi",&HB("edx"));             # rk[11]>>8
-               &xor    ("eax","ebx");
-
-               &movz   ("ebx",&BP(-128,$tbl,"esi",1));
-               &shr    ("edx",16);
-               &shl    ("ebx",8);
-               &movz   ("esi",&LB("edx"));             # rk[11]>>16
-               &xor    ("eax","ebx");
-
-               &movz   ("ebx",&BP(-128,$tbl,"esi",1));
-               &movz   ("esi",&HB("edx"));             # rk[11]>>24
-               &shl    ("ebx",16);
-               &xor    ("eax","ebx");
-
-               &movz   ("ebx",&BP(-128,$tbl,"esi",1));
-               &shl    ("ebx",24);
-               &xor    ("eax","ebx");
-
-               &mov    (&DWP(48,"edi"),"eax");         # rk[12]
-               &xor    ("eax",&DWP(20,"edi"));
-               &mov    (&DWP(52,"edi"),"eax");         # rk[13]
-               &xor    ("eax",&DWP(24,"edi"));
-               &mov    (&DWP(56,"edi"),"eax");         # rk[14]
-               &xor    ("eax",&DWP(28,"edi"));
-               &mov    (&DWP(60,"edi"),"eax");         # rk[15]
-
-               &add    ("edi",32);
-       &jmp    (&label("14loop"));
-
-       &set_label("14break");
-       &mov    (&DWP(48,"edi"),14);            # setup number of rounds
-       &xor    ("eax","eax");
-       &jmp    (&label("exit"));
-
-    &set_label("badpointer");
-       &mov    ("eax",-1);
-    &set_label("exit");
-&function_end("_x86_AES_set_encrypt_key");
-
-# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-#                        AES_KEY *key)
-&function_begin_B("AES_set_encrypt_key");
-       &call   ("_x86_AES_set_encrypt_key");
-       &ret    ();
-&function_end_B("AES_set_encrypt_key");
-
-sub deckey()
-{ my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_;
-  my $tmp = $tbl;
-
-       &mov    ($tmp,0x80808080);
-       &and    ($tmp,$tp1);
-       &lea    ($tp2,&DWP(0,$tp1,$tp1));
-       &mov    ($acc,$tmp);
-       &shr    ($tmp,7);
-       &sub    ($acc,$tmp);
-       &and    ($tp2,0xfefefefe);
-       &and    ($acc,0x1b1b1b1b);
-       &xor    ($tp2,$acc);
-       &mov    ($tmp,0x80808080);
-
-       &and    ($tmp,$tp2);
-       &lea    ($tp4,&DWP(0,$tp2,$tp2));
-       &mov    ($acc,$tmp);
-       &shr    ($tmp,7);
-       &sub    ($acc,$tmp);
-       &and    ($tp4,0xfefefefe);
-       &and    ($acc,0x1b1b1b1b);
-        &xor   ($tp2,$tp1);    # tp2^tp1
-       &xor    ($tp4,$acc);
-       &mov    ($tmp,0x80808080);
-
-       &and    ($tmp,$tp4);
-       &lea    ($tp8,&DWP(0,$tp4,$tp4));
-       &mov    ($acc,$tmp);
-       &shr    ($tmp,7);
-        &xor   ($tp4,$tp1);    # tp4^tp1
-       &sub    ($acc,$tmp);
-       &and    ($tp8,0xfefefefe);
-       &and    ($acc,0x1b1b1b1b);
-        &rotl  ($tp1,8);       # = ROTATE(tp1,8)
-       &xor    ($tp8,$acc);
-
-       &mov    ($tmp,&DWP(4*($i+1),$key));     # modulo-scheduled load
-
-       &xor    ($tp1,$tp2);
-       &xor    ($tp2,$tp8);
-       &xor    ($tp1,$tp4);
-       &rotl   ($tp2,24);
-       &xor    ($tp4,$tp8);
-       &xor    ($tp1,$tp8);    # ^= tp8^(tp4^tp1)^(tp2^tp1)
-       &rotl   ($tp4,16);
-       &xor    ($tp1,$tp2);    # ^= ROTATE(tp8^tp2^tp1,24)
-       &rotl   ($tp8,8);
-       &xor    ($tp1,$tp4);    # ^= ROTATE(tp8^tp4^tp1,16)
-       &mov    ($tp2,$tmp);
-       &xor    ($tp1,$tp8);    # ^= ROTATE(tp8,8)
-
-       &mov    (&DWP(4*$i,$key),$tp1);
-}
-
-# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
-#                        AES_KEY *key)
-&function_begin_B("AES_set_decrypt_key");
-       &call   ("_x86_AES_set_encrypt_key");
-       &cmp    ("eax",0);
-       &je     (&label("proceed"));
-       &ret    ();
-
-    &set_label("proceed");
-       &push   ("ebp");
-       &push   ("ebx");
-       &push   ("esi");
-       &push   ("edi");
-
-       &mov    ("esi",&wparam(2));
-       &mov    ("ecx",&DWP(240,"esi"));        # pull number of rounds
-       &lea    ("ecx",&DWP(0,"","ecx",4));
-       &lea    ("edi",&DWP(0,"esi","ecx",4));  # pointer to last chunk
-
-       &set_label("invert",4);                 # invert order of chunks
-               &mov    ("eax",&DWP(0,"esi"));
-               &mov    ("ebx",&DWP(4,"esi"));
-               &mov    ("ecx",&DWP(0,"edi"));
-               &mov    ("edx",&DWP(4,"edi"));
-               &mov    (&DWP(0,"edi"),"eax");
-               &mov    (&DWP(4,"edi"),"ebx");
-               &mov    (&DWP(0,"esi"),"ecx");
-               &mov    (&DWP(4,"esi"),"edx");
-               &mov    ("eax",&DWP(8,"esi"));
-               &mov    ("ebx",&DWP(12,"esi"));
-               &mov    ("ecx",&DWP(8,"edi"));
-               &mov    ("edx",&DWP(12,"edi"));
-               &mov    (&DWP(8,"edi"),"eax");
-               &mov    (&DWP(12,"edi"),"ebx");
-               &mov    (&DWP(8,"esi"),"ecx");
-               &mov    (&DWP(12,"esi"),"edx");
-               &add    ("esi",16);
-               &sub    ("edi",16);
-               &cmp    ("esi","edi");
-       &jne    (&label("invert"));
-
-       &mov    ($key,&wparam(2));
-       &mov    ($acc,&DWP(240,$key));          # pull number of rounds
-       &lea    ($acc,&DWP(-2,$acc,$acc));
-       &lea    ($acc,&DWP(0,$key,$acc,8));
-       &mov    (&wparam(2),$acc);
-
-       &mov    ($s0,&DWP(16,$key));            # modulo-scheduled load
-       &set_label("permute",4);                # permute the key schedule
-               &add    ($key,16);
-               &deckey (0,$key,$s0,$s1,$s2,$s3);
-               &deckey (1,$key,$s1,$s2,$s3,$s0);
-               &deckey (2,$key,$s2,$s3,$s0,$s1);
-               &deckey (3,$key,$s3,$s0,$s1,$s2);
-               &cmp    ($key,&wparam(2));
-       &jb     (&label("permute"));
-
-       &xor    ("eax","eax");                  # return success
-&function_end("AES_set_decrypt_key");
-&asciz("AES for x86, CRYPTOGAMS by <appro\@openssl.org>");
-
-&asm_finish();
-
-close STDOUT;
index 0c40059..815fde8 100644 (file)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
 # Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
 # for 128-bit keys, if hardware support is detected.
 
-# Januray 2009.
+# January 2009.
 #
 # Add support for hardware AES192/256 and reschedule instructions to
 # minimize/avoid Address Generation Interlock hazard and to favour
 # dual-issue z10 pipeline. This gave ~25% improvement on z10 and
 # almost 50% on z9. The gain is smaller on z10, because being dual-
 # issue z10 makes it impossible to eliminate the interlock condition:
-# critial path is not long enough. Yet it spends ~24 cycles per byte
+# critical path is not long enough. Yet it spends ~24 cycles per byte
 # processed with 128-bit key.
 #
 # Unlike previous version hardware support detection takes place only
diff --git a/crypto/aes/asm/aes-x86_64.pl b/crypto/aes/asm/aes-x86_64.pl
deleted file mode 100755 (executable)
index d87e201..0000000
+++ /dev/null
@@ -1,2916 +0,0 @@
-#! /usr/bin/env perl
-# Copyright 2005-2019 The OpenSSL Project Authors. All Rights Reserved.
-#
-# Licensed under the OpenSSL license (the "License").  You may not use
-# this file except in compliance with the License.  You can obtain a copy
-# in the file LICENSE in the source distribution or at
-# https://www.openssl.org/source/license.html
-
-#
-# ====================================================================
-# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-#
-# Version 2.1.
-#
-# aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on
-# Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version
-# [you'll notice a lot of resemblance], such as compressed S-boxes
-# in little-endian byte order, prefetch of these tables in CBC mode,
-# as well as avoiding L1 cache aliasing between stack frame and key
-# schedule and already mentioned tables, compressed Td4...
-#
-# Performance in number of cycles per processed byte for 128-bit key:
-#
-#              ECB encrypt     ECB decrypt     CBC large chunk
-# AMD64                33              43              13.0
-# EM64T                38              56              18.6(*)
-# Core 2       30              42              14.5(*)
-# Atom         65              86              32.1(*)
-#
-# (*) with hyper-threading off
-
-$flavour = shift;
-$output  = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-
-$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\"";
-*STDOUT=*OUT;
-
-$verticalspin=1;       # unlike 32-bit version $verticalspin performs
-                       # ~15% better on both AMD and Intel cores
-$speed_limit=512;      # see aes-586.pl for details
-
-$code=".text\n";
-
-$s0="%eax";
-$s1="%ebx";
-$s2="%ecx";
-$s3="%edx";
-$acc0="%esi";  $mask80="%rsi";
-$acc1="%edi";  $maskfe="%rdi";
-$acc2="%ebp";  $mask1b="%rbp";
-$inp="%r8";
-$out="%r9";
-$t0="%r10d";
-$t1="%r11d";
-$t2="%r12d";
-$rnds="%r13d";
-$sbox="%r14";
-$key="%r15";
-
-sub hi() { my $r=shift;        $r =~ s/%[er]([a-d])x/%\1h/;    $r; }
-sub lo() { my $r=shift;        $r =~ s/%[er]([a-d])x/%\1l/;
-                       $r =~ s/%[er]([sd]i)/%\1l/;
-                       $r =~ s/%(r[0-9]+)[d]?/%\1b/;   $r; }
-sub LO() { my $r=shift; $r =~ s/%r([a-z]+)/%e\1/;
-                       $r =~ s/%r([0-9]+)/%r\1d/;      $r; }
-sub _data_word()
-{ my $i;
-    while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
-}
-sub data_word()
-{ my $i;
-  my $last=pop(@_);
-    $code.=".long\t";
-    while(defined($i=shift)) { $code.=sprintf"0x%08x,",$i; }
-    $code.=sprintf"0x%08x\n",$last;
-}
-
-sub data_byte()
-{ my $i;
-  my $last=pop(@_);
-    $code.=".byte\t";
-    while(defined($i=shift)) { $code.=sprintf"0x%02x,",$i&0xff; }
-    $code.=sprintf"0x%02x\n",$last&0xff;
-}
-
-sub encvert()
-{ my $t3="%r8d";       # zaps $inp!
-
-$code.=<<___;
-       # favor 3-way issue Opteron pipeline...
-       movzb   `&lo("$s0")`,$acc0
-       movzb   `&lo("$s1")`,$acc1
-       movzb   `&lo("$s2")`,$acc2
-       mov     0($sbox,$acc0,8),$t0
-       mov     0($sbox,$acc1,8),$t1
-       mov     0($sbox,$acc2,8),$t2
-
-       movzb   `&hi("$s1")`,$acc0
-       movzb   `&hi("$s2")`,$acc1
-       movzb   `&lo("$s3")`,$acc2
-       xor     3($sbox,$acc0,8),$t0
-       xor     3($sbox,$acc1,8),$t1
-       mov     0($sbox,$acc2,8),$t3
-
-       movzb   `&hi("$s3")`,$acc0
-       shr     \$16,$s2
-       movzb   `&hi("$s0")`,$acc2
-       xor     3($sbox,$acc0,8),$t2
-       shr     \$16,$s3
-       xor     3($sbox,$acc2,8),$t3
-
-       shr     \$16,$s1
-       lea     16($key),$key
-       shr     \$16,$s0
-
-       movzb   `&lo("$s2")`,$acc0
-       movzb   `&lo("$s3")`,$acc1
-       movzb   `&lo("$s0")`,$acc2
-       xor     2($sbox,$acc0,8),$t0
-       xor     2($sbox,$acc1,8),$t1
-       xor     2($sbox,$acc2,8),$t2
-
-       movzb   `&hi("$s3")`,$acc0
-       movzb   `&hi("$s0")`,$acc1
-       movzb   `&lo("$s1")`,$acc2
-       xor     1($sbox,$acc0,8),$t0
-       xor     1($sbox,$acc1,8),$t1
-       xor     2($sbox,$acc2,8),$t3
-
-       mov     12($key),$s3
-       movzb   `&hi("$s1")`,$acc1
-       movzb   `&hi("$s2")`,$acc2
-       mov     0($key),$s0
-       xor     1($sbox,$acc1,8),$t2
-       xor     1($sbox,$acc2,8),$t3
-
-       mov     4($key),$s1
-       mov     8($key),$s2
-       xor     $t0,$s0
-       xor     $t1,$s1
-       xor     $t2,$s2
-       xor     $t3,$s3
-___
-}
-
-sub enclastvert()
-{ my $t3="%r8d";       # zaps $inp!
-
-$code.=<<___;
-       movzb   `&lo("$s0")`,$acc0
-       movzb   `&lo("$s1")`,$acc1
-       movzb   `&lo("$s2")`,$acc2
-       movzb   2($sbox,$acc0,8),$t0
-       movzb   2($sbox,$acc1,8),$t1
-       movzb   2($sbox,$acc2,8),$t2
-
-       movzb   `&lo("$s3")`,$acc0
-       movzb   `&hi("$s1")`,$acc1
-       movzb   `&hi("$s2")`,$acc2
-       movzb   2($sbox,$acc0,8),$t3
-       mov     0($sbox,$acc1,8),$acc1  #$t0
-       mov     0($sbox,$acc2,8),$acc2  #$t1
-
-       and     \$0x0000ff00,$acc1
-       and     \$0x0000ff00,$acc2
-
-       xor     $acc1,$t0
-       xor     $acc2,$t1
-       shr     \$16,$s2
-
-       movzb   `&hi("$s3")`,$acc0
-       movzb   `&hi("$s0")`,$acc1
-       shr     \$16,$s3
-       mov     0($sbox,$acc0,8),$acc0  #$t2
-       mov     0($sbox,$acc1,8),$acc1  #$t3
-
-       and     \$0x0000ff00,$acc0
-       and     \$0x0000ff00,$acc1
-       shr     \$16,$s1
-       xor     $acc0,$t2
-       xor     $acc1,$t3
-       shr     \$16,$s0
-
-       movzb   `&lo("$s2")`,$acc0
-       movzb   `&lo("$s3")`,$acc1
-       movzb   `&lo("$s0")`,$acc2
-       mov     0($sbox,$acc0,8),$acc0  #$t0
-       mov     0($sbox,$acc1,8),$acc1  #$t1
-       mov     0($sbox,$acc2,8),$acc2  #$t2
-
-       and     \$0x00ff0000,$acc0
-       and     \$0x00ff0000,$acc1
-       and     \$0x00ff0000,$acc2
-
-       xor     $acc0,$t0
-       xor     $acc1,$t1
-       xor     $acc2,$t2
-
-       movzb   `&lo("$s1")`,$acc0
-       movzb   `&hi("$s3")`,$acc1
-       movzb   `&hi("$s0")`,$acc2
-       mov     0($sbox,$acc0,8),$acc0  #$t3
-       mov     2($sbox,$acc1,8),$acc1  #$t0
-       mov     2($sbox,$acc2,8),$acc2  #$t1
-
-       and     \$0x00ff0000,$acc0
-       and     \$0xff000000,$acc1
-       and     \$0xff000000,$acc2
-
-       xor     $acc0,$t3
-       xor     $acc1,$t0
-       xor     $acc2,$t1
-
-       movzb   `&hi("$s1")`,$acc0
-       movzb   `&hi("$s2")`,$acc1
-       mov     16+12($key),$s3
-       mov     2($sbox,$acc0,8),$acc0  #$t2
-       mov     2($sbox,$acc1,8),$acc1  #$t3
-       mov     16+0($key),$s0
-
-       and     \$0xff000000,$acc0
-       and     \$0xff000000,$acc1
-
-       xor     $acc0,$t2
-       xor     $acc1,$t3
-
-       mov     16+4($key),$s1
-       mov     16+8($key),$s2
-       xor     $t0,$s0
-       xor     $t1,$s1
-       xor     $t2,$s2
-       xor     $t3,$s3
-___
-}
-
-sub encstep()
-{ my ($i,@s) = @_;
-  my $tmp0=$acc0;
-  my $tmp1=$acc1;
-  my $tmp2=$acc2;
-  my $out=($t0,$t1,$t2,$s[0])[$i];
-
-       if ($i==3) {
-               $tmp0=$s[1];
-               $tmp1=$s[2];
-               $tmp2=$s[3];
-       }
-       $code.="        movzb   ".&lo($s[0]).",$out\n";
-       $code.="        mov     $s[2],$tmp1\n"          if ($i!=3);
-       $code.="        lea     16($key),$key\n"        if ($i==0);
-
-       $code.="        movzb   ".&hi($s[1]).",$tmp0\n";
-       $code.="        mov     0($sbox,$out,8),$out\n";
-
-       $code.="        shr     \$16,$tmp1\n";
-       $code.="        mov     $s[3],$tmp2\n"          if ($i!=3);
-       $code.="        xor     3($sbox,$tmp0,8),$out\n";
-
-       $code.="        movzb   ".&lo($tmp1).",$tmp1\n";
-       $code.="        shr     \$24,$tmp2\n";
-       $code.="        xor     4*$i($key),$out\n";
-
-       $code.="        xor     2($sbox,$tmp1,8),$out\n";
-       $code.="        xor     1($sbox,$tmp2,8),$out\n";
-
-       $code.="        mov     $t0,$s[1]\n"            if ($i==3);
-       $code.="        mov     $t1,$s[2]\n"            if ($i==3);
-       $code.="        mov     $t2,$s[3]\n"            if ($i==3);
-       $code.="\n";
-}
-
-sub enclast()
-{ my ($i,@s)=@_;
-  my $tmp0=$acc0;
-  my $tmp1=$acc1;
-  my $tmp2=$acc2;
-  my $out=($t0,$t1,$t2,$s[0])[$i];
-
-       if ($i==3) {
-               $tmp0=$s[1];
-               $tmp1=$s[2];
-               $tmp2=$s[3];
-       }
-       $code.="        movzb   ".&lo($s[0]).",$out\n";
-       $code.="        mov     $s[2],$tmp1\n"          if ($i!=3);
-
-       $code.="        mov     2($sbox,$out,8),$out\n";
-       $code.="        shr     \$16,$tmp1\n";
-       $code.="        mov     $s[3],$tmp2\n"          if ($i!=3);
-
-       $code.="        and     \$0x000000ff,$out\n";
-       $code.="        movzb   ".&hi($s[1]).",$tmp0\n";
-       $code.="        movzb   ".&lo($tmp1).",$tmp1\n";
-       $code.="        shr     \$24,$tmp2\n";
-
-       $code.="        mov     0($sbox,$tmp0,8),$tmp0\n";
-       $code.="        mov     0($sbox,$tmp1,8),$tmp1\n";
-       $code.="        mov     2($sbox,$tmp2,8),$tmp2\n";
-
-       $code.="        and     \$0x0000ff00,$tmp0\n";
-       $code.="        and     \$0x00ff0000,$tmp1\n";
-       $code.="        and     \$0xff000000,$tmp2\n";
-
-       $code.="        xor     $tmp0,$out\n";
-       $code.="        mov     $t0,$s[1]\n"            if ($i==3);
-       $code.="        xor     $tmp1,$out\n";
-       $code.="        mov     $t1,$s[2]\n"            if ($i==3);
-       $code.="        xor     $tmp2,$out\n";
-       $code.="        mov     $t2,$s[3]\n"            if ($i==3);
-       $code.="\n";
-}
-
-$code.=<<___;
-.type  _x86_64_AES_encrypt,\@abi-omnipotent
-.align 16
-_x86_64_AES_encrypt:
-       xor     0($key),$s0                     # xor with key
-       xor     4($key),$s1
-       xor     8($key),$s2
-       xor     12($key),$s3
-
-       mov     240($key),$rnds                 # load key->rounds
-       sub     \$1,$rnds
-       jmp     .Lenc_loop
-.align 16
-.Lenc_loop:
-___
-       if ($verticalspin) { &encvert(); }
-       else {  &encstep(0,$s0,$s1,$s2,$s3);
-               &encstep(1,$s1,$s2,$s3,$s0);
-               &encstep(2,$s2,$s3,$s0,$s1);
-               &encstep(3,$s3,$s0,$s1,$s2);
-       }
-$code.=<<___;
-       sub     \$1,$rnds
-       jnz     .Lenc_loop
-___
-       if ($verticalspin) { &enclastvert(); }
-       else {  &enclast(0,$s0,$s1,$s2,$s3);
-               &enclast(1,$s1,$s2,$s3,$s0);
-               &enclast(2,$s2,$s3,$s0,$s1);
-               &enclast(3,$s3,$s0,$s1,$s2);
-               $code.=<<___;
-               xor     16+0($key),$s0          # xor with key
-               xor     16+4($key),$s1
-               xor     16+8($key),$s2
-               xor     16+12($key),$s3
-___
-       }
-$code.=<<___;
-       .byte   0xf3,0xc3                       # rep ret
-.size  _x86_64_AES_encrypt,.-_x86_64_AES_encrypt
-___
-
-# it's possible to implement this by shifting tN by 8, filling least
-# significant byte with byte load and finally bswap-ing at the end,
-# but such partial register load kills Core 2...
-sub enccompactvert()
-{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
-
-$code.=<<___;
-       movzb   `&lo("$s0")`,$t0
-       movzb   `&lo("$s1")`,$t1
-       movzb   `&lo("$s2")`,$t2
-       movzb   `&lo("$s3")`,$t3
-       movzb   `&hi("$s1")`,$acc0
-       movzb   `&hi("$s2")`,$acc1
-       shr     \$16,$s2
-       movzb   `&hi("$s3")`,$acc2
-       movzb   ($sbox,$t0,1),$t0
-       movzb   ($sbox,$t1,1),$t1
-       movzb   ($sbox,$t2,1),$t2
-       movzb   ($sbox,$t3,1),$t3
-
-       movzb   ($sbox,$acc0,1),$t4     #$t0
-       movzb   `&hi("$s0")`,$acc0
-       movzb   ($sbox,$acc1,1),$t5     #$t1
-       movzb   `&lo("$s2")`,$acc1
-       movzb   ($sbox,$acc2,1),$acc2   #$t2
-       movzb   ($sbox,$acc0,1),$acc0   #$t3
-
-       shl     \$8,$t4
-       shr     \$16,$s3
-       shl     \$8,$t5
-       xor     $t4,$t0
-       shr     \$16,$s0
-       movzb   `&lo("$s3")`,$t4
-       shr     \$16,$s1
-       xor     $t5,$t1
-       shl     \$8,$acc2
-       movzb   `&lo("$s0")`,$t5
-       movzb   ($sbox,$acc1,1),$acc1   #$t0
-       xor     $acc2,$t2
-
-       shl     \$8,$acc0
-       movzb   `&lo("$s1")`,$acc2
-       shl     \$16,$acc1
-       xor     $acc0,$t3
-       movzb   ($sbox,$t4,1),$t4       #$t1
-       movzb   `&hi("$s3")`,$acc0
-       movzb   ($sbox,$t5,1),$t5       #$t2
-       xor     $acc1,$t0
-
-       shr     \$8,$s2
-       movzb   `&hi("$s0")`,$acc1
-       shl     \$16,$t4
-       shr     \$8,$s1
-       shl     \$16,$t5
-       xor     $t4,$t1
-       movzb   ($sbox,$acc2,1),$acc2   #$t3
-       movzb   ($sbox,$acc0,1),$acc0   #$t0
-       movzb   ($sbox,$acc1,1),$acc1   #$t1
-       movzb   ($sbox,$s2,1),$s3       #$t3
-       movzb   ($sbox,$s1,1),$s2       #$t2
-
-       shl     \$16,$acc2
-       xor     $t5,$t2
-       shl     \$24,$acc0
-       xor     $acc2,$t3
-       shl     \$24,$acc1
-       xor     $acc0,$t0
-       shl     \$24,$s3
-       xor     $acc1,$t1
-       shl     \$24,$s2
-       mov     $t0,$s0
-       mov     $t1,$s1
-       xor     $t2,$s2
-       xor     $t3,$s3
-___
-}
-
-sub enctransform_ref()
-{ my $sn = shift;
-  my ($acc,$r2,$tmp)=("%r8d","%r9d","%r13d");
-
-$code.=<<___;
-       mov     $sn,$acc
-       and     \$0x80808080,$acc
-       mov     $acc,$tmp
-       shr     \$7,$tmp
-       lea     ($sn,$sn),$r2
-       sub     $tmp,$acc
-       and     \$0xfefefefe,$r2
-       and     \$0x1b1b1b1b,$acc
-       mov     $sn,$tmp
-       xor     $acc,$r2
-
-       xor     $r2,$sn
-       rol     \$24,$sn
-       xor     $r2,$sn
-       ror     \$16,$tmp
-       xor     $tmp,$sn
-       ror     \$8,$tmp
-       xor     $tmp,$sn
-___
-}
-
-# unlike decrypt case it does not pay off to parallelize enctransform
-sub enctransform()
-{ my ($t3,$r20,$r21)=($acc2,"%r8d","%r9d");
-
-$code.=<<___;
-       mov     \$0x80808080,$t0
-       mov     \$0x80808080,$t1
-       and     $s0,$t0
-       and     $s1,$t1
-       mov     $t0,$acc0
-       mov     $t1,$acc1
-       shr     \$7,$t0
-       lea     ($s0,$s0),$r20
-       shr     \$7,$t1
-       lea     ($s1,$s1),$r21
-       sub     $t0,$acc0
-       sub     $t1,$acc1
-       and     \$0xfefefefe,$r20
-       and     \$0xfefefefe,$r21
-       and     \$0x1b1b1b1b,$acc0
-       and     \$0x1b1b1b1b,$acc1
-       mov     $s0,$t0
-       mov     $s1,$t1
-       xor     $acc0,$r20
-       xor     $acc1,$r21
-
-       xor     $r20,$s0
-       xor     $r21,$s1
-        mov    \$0x80808080,$t2
-       rol     \$24,$s0
-        mov    \$0x80808080,$t3
-       rol     \$24,$s1
-        and    $s2,$t2
-        and    $s3,$t3
-       xor     $r20,$s0
-       xor     $r21,$s1
-        mov    $t2,$acc0
-       ror     \$16,$t0
-        mov    $t3,$acc1
-       ror     \$16,$t1
-        lea    ($s2,$s2),$r20
-        shr    \$7,$t2
-       xor     $t0,$s0
-        shr    \$7,$t3
-       xor     $t1,$s1
-       ror     \$8,$t0
-        lea    ($s3,$s3),$r21
-       ror     \$8,$t1
-        sub    $t2,$acc0
-        sub    $t3,$acc1
-       xor     $t0,$s0
-       xor     $t1,$s1
-
-       and     \$0xfefefefe,$r20
-       and     \$0xfefefefe,$r21
-       and     \$0x1b1b1b1b,$acc0
-       and     \$0x1b1b1b1b,$acc1
-       mov     $s2,$t2
-       mov     $s3,$t3
-       xor     $acc0,$r20
-       xor     $acc1,$r21
-
-       ror     \$16,$t2
-       xor     $r20,$s2
-       ror     \$16,$t3
-       xor     $r21,$s3
-       rol     \$24,$s2
-       mov     0($sbox),$acc0                  # prefetch Te4
-       rol     \$24,$s3
-       xor     $r20,$s2
-       mov     64($sbox),$acc1
-       xor     $r21,$s3
-       mov     128($sbox),$r20
-       xor     $t2,$s2
-       ror     \$8,$t2
-       xor     $t3,$s3
-       ror     \$8,$t3
-       xor     $t2,$s2
-       mov     192($sbox),$r21
-       xor     $t3,$s3
-___
-}
-
-$code.=<<___;
-.type  _x86_64_AES_encrypt_compact,\@abi-omnipotent
-.align 16
-_x86_64_AES_encrypt_compact:
-.cfi_startproc
-       lea     128($sbox),$inp                 # size optimization
-       mov     0-128($inp),$acc1               # prefetch Te4
-       mov     32-128($inp),$acc2
-       mov     64-128($inp),$t0
-       mov     96-128($inp),$t1
-       mov     128-128($inp),$acc1
-       mov     160-128($inp),$acc2
-       mov     192-128($inp),$t0
-       mov     224-128($inp),$t1
-       jmp     .Lenc_loop_compact
-.align 16
-.Lenc_loop_compact:
-               xor     0($key),$s0             # xor with key
-               xor     4($key),$s1
-               xor     8($key),$s2
-               xor     12($key),$s3
-               lea     16($key),$key
-___
-               &enccompactvert();
-$code.=<<___;
-               cmp     16(%rsp),$key
-               je      .Lenc_compact_done
-___
-               &enctransform();
-$code.=<<___;
-       jmp     .Lenc_loop_compact
-.align 16
-.Lenc_compact_done:
-       xor     0($key),$s0
-       xor     4($key),$s1
-       xor     8($key),$s2
-       xor     12($key),$s3
-       .byte   0xf3,0xc3                       # rep ret
-.cfi_endproc
-.size  _x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
-___
-
-# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
-$code.=<<___;
-.globl AES_encrypt
-.type  AES_encrypt,\@function,3
-.align 16
-.globl asm_AES_encrypt
-.hidden        asm_AES_encrypt
-asm_AES_encrypt:
-AES_encrypt:
-.cfi_startproc
-       mov     %rsp,%rax
-.cfi_def_cfa_register  %rax
-       push    %rbx
-.cfi_push      %rbx
-       push    %rbp
-.cfi_push      %rbp
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-
-       # allocate frame "above" key schedule
-       lea     -63(%rdx),%rcx  # %rdx is key argument
-       and     \$-64,%rsp
-       sub     %rsp,%rcx
-       neg     %rcx
-       and     \$0x3c0,%rcx
-       sub     %rcx,%rsp
-       sub     \$32,%rsp
-
-       mov     %rsi,16(%rsp)   # save out
-       mov     %rax,24(%rsp)   # save original stack pointer
-.cfi_cfa_expression    %rsp+24,deref,+8
-.Lenc_prologue:
-
-       mov     %rdx,$key
-       mov     240($key),$rnds # load rounds
-
-       mov     0(%rdi),$s0     # load input vector
-       mov     4(%rdi),$s1
-       mov     8(%rdi),$s2
-       mov     12(%rdi),$s3
-
-       shl     \$4,$rnds
-       lea     ($key,$rnds),%rbp
-       mov     $key,(%rsp)     # key schedule
-       mov     %rbp,8(%rsp)    # end of key schedule
-
-       # pick Te4 copy which can't "overlap" with stack frame or key schedule
-       lea     .LAES_Te+2048(%rip),$sbox
-       lea     768(%rsp),%rbp
-       sub     $sbox,%rbp
-       and     \$0x300,%rbp
-       lea     ($sbox,%rbp),$sbox
-
-       call    _x86_64_AES_encrypt_compact
-
-       mov     16(%rsp),$out   # restore out
-       mov     24(%rsp),%rsi   # restore saved stack pointer
-.cfi_def_cfa   %rsi,8
-       mov     $s0,0($out)     # write output vector
-       mov     $s1,4($out)
-       mov     $s2,8($out)
-       mov     $s3,12($out)
-
-       mov     -48(%rsi),%r15
-.cfi_restore   %r15
-       mov     -40(%rsi),%r14
-.cfi_restore   %r14
-       mov     -32(%rsi),%r13
-.cfi_restore   %r13
-       mov     -24(%rsi),%r12
-.cfi_restore   %r12
-       mov     -16(%rsi),%rbp
-.cfi_restore   %rbp
-       mov     -8(%rsi),%rbx
-.cfi_restore   %rbx
-       lea     (%rsi),%rsp
-.cfi_def_cfa_register  %rsp
-.Lenc_epilogue:
-       ret
-.cfi_endproc
-.size  AES_encrypt,.-AES_encrypt
-___
-
-#------------------------------------------------------------------#
-
-sub decvert()
-{ my $t3="%r8d";       # zaps $inp!
-
-$code.=<<___;
-       # favor 3-way issue Opteron pipeline...
-       movzb   `&lo("$s0")`,$acc0
-       movzb   `&lo("$s1")`,$acc1
-       movzb   `&lo("$s2")`,$acc2
-       mov     0($sbox,$acc0,8),$t0
-       mov     0($sbox,$acc1,8),$t1
-       mov     0($sbox,$acc2,8),$t2
-
-       movzb   `&hi("$s3")`,$acc0
-       movzb   `&hi("$s0")`,$acc1
-       movzb   `&lo("$s3")`,$acc2
-       xor     3($sbox,$acc0,8),$t0
-       xor     3($sbox,$acc1,8),$t1
-       mov     0($sbox,$acc2,8),$t3
-
-       movzb   `&hi("$s1")`,$acc0
-       shr     \$16,$s0
-       movzb   `&hi("$s2")`,$acc2
-       xor     3($sbox,$acc0,8),$t2
-       shr     \$16,$s3
-       xor     3($sbox,$acc2,8),$t3
-
-       shr     \$16,$s1
-       lea     16($key),$key
-       shr     \$16,$s2
-
-       movzb   `&lo("$s2")`,$acc0
-       movzb   `&lo("$s3")`,$acc1
-       movzb   `&lo("$s0")`,$acc2
-       xor     2($sbox,$acc0,8),$t0
-       xor     2($sbox,$acc1,8),$t1
-       xor     2($sbox,$acc2,8),$t2
-
-       movzb   `&hi("$s1")`,$acc0
-       movzb   `&hi("$s2")`,$acc1
-       movzb   `&lo("$s1")`,$acc2
-       xor     1($sbox,$acc0,8),$t0
-       xor     1($sbox,$acc1,8),$t1
-       xor     2($sbox,$acc2,8),$t3
-
-       movzb   `&hi("$s3")`,$acc0
-       mov     12($key),$s3
-       movzb   `&hi("$s0")`,$acc2
-       xor     1($sbox,$acc0,8),$t2
-       mov     0($key),$s0
-       xor     1($sbox,$acc2,8),$t3
-
-       xor     $t0,$s0
-       mov     4($key),$s1
-       mov     8($key),$s2
-       xor     $t2,$s2
-       xor     $t1,$s1
-       xor     $t3,$s3
-___
-}
-
-sub declastvert()
-{ my $t3="%r8d";       # zaps $inp!
-
-$code.=<<___;
-       lea     2048($sbox),$sbox       # size optimization
-       movzb   `&lo("$s0")`,$acc0
-       movzb   `&lo("$s1")`,$acc1
-       movzb   `&lo("$s2")`,$acc2
-       movzb   ($sbox,$acc0,1),$t0
-       movzb   ($sbox,$acc1,1),$t1
-       movzb   ($sbox,$acc2,1),$t2
-
-       movzb   `&lo("$s3")`,$acc0
-       movzb   `&hi("$s3")`,$acc1
-       movzb   `&hi("$s0")`,$acc2
-       movzb   ($sbox,$acc0,1),$t3
-       movzb   ($sbox,$acc1,1),$acc1   #$t0
-       movzb   ($sbox,$acc2,1),$acc2   #$t1
-
-       shl     \$8,$acc1
-       shl     \$8,$acc2
-
-       xor     $acc1,$t0
-       xor     $acc2,$t1
-       shr     \$16,$s3
-
-       movzb   `&hi("$s1")`,$acc0
-       movzb   `&hi("$s2")`,$acc1
-       shr     \$16,$s0
-       movzb   ($sbox,$acc0,1),$acc0   #$t2
-       movzb   ($sbox,$acc1,1),$acc1   #$t3
-
-       shl     \$8,$acc0
-       shl     \$8,$acc1
-       shr     \$16,$s1
-       xor     $acc0,$t2
-       xor     $acc1,$t3
-       shr     \$16,$s2
-
-       movzb   `&lo("$s2")`,$acc0
-       movzb   `&lo("$s3")`,$acc1
-       movzb   `&lo("$s0")`,$acc2
-       movzb   ($sbox,$acc0,1),$acc0   #$t0
-       movzb   ($sbox,$acc1,1),$acc1   #$t1
-       movzb   ($sbox,$acc2,1),$acc2   #$t2
-
-       shl     \$16,$acc0
-       shl     \$16,$acc1
-       shl     \$16,$acc2
-
-       xor     $acc0,$t0
-       xor     $acc1,$t1
-       xor     $acc2,$t2
-
-       movzb   `&lo("$s1")`,$acc0
-       movzb   `&hi("$s1")`,$acc1
-       movzb   `&hi("$s2")`,$acc2
-       movzb   ($sbox,$acc0,1),$acc0   #$t3
-       movzb   ($sbox,$acc1,1),$acc1   #$t0
-       movzb   ($sbox,$acc2,1),$acc2   #$t1
-
-       shl     \$16,$acc0
-       shl     \$24,$acc1
-       shl     \$24,$acc2
-
-       xor     $acc0,$t3
-       xor     $acc1,$t0
-       xor     $acc2,$t1
-
-       movzb   `&hi("$s3")`,$acc0
-       movzb   `&hi("$s0")`,$acc1
-       mov     16+12($key),$s3
-       movzb   ($sbox,$acc0,1),$acc0   #$t2
-       movzb   ($sbox,$acc1,1),$acc1   #$t3
-       mov     16+0($key),$s0
-
-       shl     \$24,$acc0
-       shl     \$24,$acc1
-
-       xor     $acc0,$t2
-       xor     $acc1,$t3
-
-       mov     16+4($key),$s1
-       mov     16+8($key),$s2
-       lea     -2048($sbox),$sbox
-       xor     $t0,$s0
-       xor     $t1,$s1
-       xor     $t2,$s2
-       xor     $t3,$s3
-___
-}
-
-sub decstep()
-{ my ($i,@s) = @_;
-  my $tmp0=$acc0;
-  my $tmp1=$acc1;
-  my $tmp2=$acc2;
-  my $out=($t0,$t1,$t2,$s[0])[$i];
-
-       $code.="        mov     $s[0],$out\n"           if ($i!=3);
-                       $tmp1=$s[2]                     if ($i==3);
-       $code.="        mov     $s[2],$tmp1\n"          if ($i!=3);
-       $code.="        and     \$0xFF,$out\n";
-
-       $code.="        mov     0($sbox,$out,8),$out\n";
-       $code.="        shr     \$16,$tmp1\n";
-                       $tmp2=$s[3]                     if ($i==3);
-       $code.="        mov     $s[3],$tmp2\n"          if ($i!=3);
-
-                       $tmp0=$s[1]                     if ($i==3);
-       $code.="        movzb   ".&hi($s[1]).",$tmp0\n";
-       $code.="        and     \$0xFF,$tmp1\n";
-       $code.="        shr     \$24,$tmp2\n";
-
-       $code.="        xor     3($sbox,$tmp0,8),$out\n";
-       $code.="        xor     2($sbox,$tmp1,8),$out\n";
-       $code.="        xor     1($sbox,$tmp2,8),$out\n";
-
-       $code.="        mov     $t2,$s[1]\n"            if ($i==3);
-       $code.="        mov     $t1,$s[2]\n"            if ($i==3);
-       $code.="        mov     $t0,$s[3]\n"            if ($i==3);
-       $code.="\n";
-}
-
-sub declast()
-{ my ($i,@s)=@_;
-  my $tmp0=$acc0;
-  my $tmp1=$acc1;
-  my $tmp2=$acc2;
-  my $out=($t0,$t1,$t2,$s[0])[$i];
-
-       $code.="        mov     $s[0],$out\n"           if ($i!=3);
-                       $tmp1=$s[2]                     if ($i==3);
-       $code.="        mov     $s[2],$tmp1\n"          if ($i!=3);
-       $code.="        and     \$0xFF,$out\n";
-
-       $code.="        movzb   2048($sbox,$out,1),$out\n";
-       $code.="        shr     \$16,$tmp1\n";
-                       $tmp2=$s[3]                     if ($i==3);
-       $code.="        mov     $s[3],$tmp2\n"          if ($i!=3);
-
-                       $tmp0=$s[1]                     if ($i==3);
-       $code.="        movzb   ".&hi($s[1]).",$tmp0\n";
-       $code.="        and     \$0xFF,$tmp1\n";
-       $code.="        shr     \$24,$tmp2\n";
-
-       $code.="        movzb   2048($sbox,$tmp0,1),$tmp0\n";
-       $code.="        movzb   2048($sbox,$tmp1,1),$tmp1\n";
-       $code.="        movzb   2048($sbox,$tmp2,1),$tmp2\n";
-
-       $code.="        shl     \$8,$tmp0\n";
-       $code.="        shl     \$16,$tmp1\n";
-       $code.="        shl     \$24,$tmp2\n";
-
-       $code.="        xor     $tmp0,$out\n";
-       $code.="        mov     $t2,$s[1]\n"            if ($i==3);
-       $code.="        xor     $tmp1,$out\n";
-       $code.="        mov     $t1,$s[2]\n"            if ($i==3);
-       $code.="        xor     $tmp2,$out\n";
-       $code.="        mov     $t0,$s[3]\n"            if ($i==3);
-       $code.="\n";
-}
-
-$code.=<<___;
-.type  _x86_64_AES_decrypt,\@abi-omnipotent
-.align 16
-_x86_64_AES_decrypt:
-       xor     0($key),$s0                     # xor with key
-       xor     4($key),$s1
-       xor     8($key),$s2
-       xor     12($key),$s3
-
-       mov     240($key),$rnds                 # load key->rounds
-       sub     \$1,$rnds
-       jmp     .Ldec_loop
-.align 16
-.Ldec_loop:
-___
-       if ($verticalspin) { &decvert(); }
-       else {  &decstep(0,$s0,$s3,$s2,$s1);
-               &decstep(1,$s1,$s0,$s3,$s2);
-               &decstep(2,$s2,$s1,$s0,$s3);
-               &decstep(3,$s3,$s2,$s1,$s0);
-               $code.=<<___;
-               lea     16($key),$key
-               xor     0($key),$s0                     # xor with key
-               xor     4($key),$s1
-               xor     8($key),$s2
-               xor     12($key),$s3
-___
-       }
-$code.=<<___;
-       sub     \$1,$rnds
-       jnz     .Ldec_loop
-___
-       if ($verticalspin) { &declastvert(); }
-       else {  &declast(0,$s0,$s3,$s2,$s1);
-               &declast(1,$s1,$s0,$s3,$s2);
-               &declast(2,$s2,$s1,$s0,$s3);
-               &declast(3,$s3,$s2,$s1,$s0);
-               $code.=<<___;
-               xor     16+0($key),$s0                  # xor with key
-               xor     16+4($key),$s1
-               xor     16+8($key),$s2
-               xor     16+12($key),$s3
-___
-       }
-$code.=<<___;
-       .byte   0xf3,0xc3                       # rep ret
-.size  _x86_64_AES_decrypt,.-_x86_64_AES_decrypt
-___
-
-sub deccompactvert()
-{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
-
-$code.=<<___;
-       movzb   `&lo("$s0")`,$t0
-       movzb   `&lo("$s1")`,$t1
-       movzb   `&lo("$s2")`,$t2
-       movzb   `&lo("$s3")`,$t3
-       movzb   `&hi("$s3")`,$acc0
-       movzb   `&hi("$s0")`,$acc1
-       shr     \$16,$s3
-       movzb   `&hi("$s1")`,$acc2
-       movzb   ($sbox,$t0,1),$t0
-       movzb   ($sbox,$t1,1),$t1
-       movzb   ($sbox,$t2,1),$t2
-       movzb   ($sbox,$t3,1),$t3
-
-       movzb   ($sbox,$acc0,1),$t4     #$t0
-       movzb   `&hi("$s2")`,$acc0
-       movzb   ($sbox,$acc1,1),$t5     #$t1
-       movzb   ($sbox,$acc2,1),$acc2   #$t2
-       movzb   ($sbox,$acc0,1),$acc0   #$t3
-
-       shr     \$16,$s2
-       shl     \$8,$t5
-       shl     \$8,$t4
-       movzb   `&lo("$s2")`,$acc1
-       shr     \$16,$s0
-       xor     $t4,$t0
-       shr     \$16,$s1
-       movzb   `&lo("$s3")`,$t4
-
-       shl     \$8,$acc2
-       xor     $t5,$t1
-       shl     \$8,$acc0
-       movzb   `&lo("$s0")`,$t5
-       movzb   ($sbox,$acc1,1),$acc1   #$t0
-       xor     $acc2,$t2
-       movzb   `&lo("$s1")`,$acc2
-
-       shl     \$16,$acc1
-       xor     $acc0,$t3
-       movzb   ($sbox,$t4,1),$t4       #$t1
-       movzb   `&hi("$s1")`,$acc0
-       movzb   ($sbox,$acc2,1),$acc2   #$t3
-       xor     $acc1,$t0
-       movzb   ($sbox,$t5,1),$t5       #$t2
-       movzb   `&hi("$s2")`,$acc1
-
-       shl     \$16,$acc2
-       shl     \$16,$t4
-       shl     \$16,$t5
-       xor     $acc2,$t3
-       movzb   `&hi("$s3")`,$acc2
-       xor     $t4,$t1
-       shr     \$8,$s0
-       xor     $t5,$t2
-
-       movzb   ($sbox,$acc0,1),$acc0   #$t0
-       movzb   ($sbox,$acc1,1),$s1     #$t1
-       movzb   ($sbox,$acc2,1),$s2     #$t2
-       movzb   ($sbox,$s0,1),$s3       #$t3
-
-       mov     $t0,$s0
-       shl     \$24,$acc0
-       shl     \$24,$s1
-       shl     \$24,$s2
-       xor     $acc0,$s0
-       shl     \$24,$s3
-       xor     $t1,$s1
-       xor     $t2,$s2
-       xor     $t3,$s3
-___
-}
-
-# parallelized version! input is pair of 64-bit values: %rax=s1.s0
-# and %rcx=s3.s2, output is four 32-bit values in %eax=s0, %ebx=s1,
-# %ecx=s2 and %edx=s3.
-sub dectransform()
-{ my ($tp10,$tp20,$tp40,$tp80,$acc0)=("%rax","%r8", "%r9", "%r10","%rbx");
-  my ($tp18,$tp28,$tp48,$tp88,$acc8)=("%rcx","%r11","%r12","%r13","%rdx");
-  my $prefetch = shift;
-
-$code.=<<___;
-       mov     $mask80,$tp40
-       mov     $mask80,$tp48
-       and     $tp10,$tp40
-       and     $tp18,$tp48
-       mov     $tp40,$acc0
-       mov     $tp48,$acc8
-       shr     \$7,$tp40
-       lea     ($tp10,$tp10),$tp20
-       shr     \$7,$tp48
-       lea     ($tp18,$tp18),$tp28
-       sub     $tp40,$acc0
-       sub     $tp48,$acc8
-       and     $maskfe,$tp20
-       and     $maskfe,$tp28
-       and     $mask1b,$acc0
-       and     $mask1b,$acc8
-       xor     $acc0,$tp20
-       xor     $acc8,$tp28
-       mov     $mask80,$tp80
-       mov     $mask80,$tp88
-
-       and     $tp20,$tp80
-       and     $tp28,$tp88
-       mov     $tp80,$acc0
-       mov     $tp88,$acc8
-       shr     \$7,$tp80
-       lea     ($tp20,$tp20),$tp40
-       shr     \$7,$tp88
-       lea     ($tp28,$tp28),$tp48
-       sub     $tp80,$acc0
-       sub     $tp88,$acc8
-       and     $maskfe,$tp40
-       and     $maskfe,$tp48
-       and     $mask1b,$acc0
-       and     $mask1b,$acc8
-       xor     $acc0,$tp40
-       xor     $acc8,$tp48
-       mov     $mask80,$tp80
-       mov     $mask80,$tp88
-
-       and     $tp40,$tp80
-       and     $tp48,$tp88
-       mov     $tp80,$acc0
-       mov     $tp88,$acc8
-       shr     \$7,$tp80
-        xor    $tp10,$tp20             # tp2^=tp1
-       shr     \$7,$tp88
-        xor    $tp18,$tp28             # tp2^=tp1
-       sub     $tp80,$acc0
-       sub     $tp88,$acc8
-       lea     ($tp40,$tp40),$tp80
-       lea     ($tp48,$tp48),$tp88
-        xor    $tp10,$tp40             # tp4^=tp1
-        xor    $tp18,$tp48             # tp4^=tp1
-       and     $maskfe,$tp80
-       and     $maskfe,$tp88
-       and     $mask1b,$acc0
-       and     $mask1b,$acc8
-       xor     $acc0,$tp80
-       xor     $acc8,$tp88
-
-       xor     $tp80,$tp10             # tp1^=tp8
-       xor     $tp88,$tp18             # tp1^=tp8
-       xor     $tp80,$tp20             # tp2^tp1^=tp8
-       xor     $tp88,$tp28             # tp2^tp1^=tp8
-       mov     $tp10,$acc0
-       mov     $tp18,$acc8
-       xor     $tp80,$tp40             # tp4^tp1^=tp8
-       shr     \$32,$acc0
-       xor     $tp88,$tp48             # tp4^tp1^=tp8
-       shr     \$32,$acc8
-       xor     $tp20,$tp80             # tp8^=tp8^tp2^tp1=tp2^tp1
-       rol     \$8,`&LO("$tp10")`      # ROTATE(tp1^tp8,8)
-       xor     $tp28,$tp88             # tp8^=tp8^tp2^tp1=tp2^tp1
-       rol     \$8,`&LO("$tp18")`      # ROTATE(tp1^tp8,8)
-       xor     $tp40,$tp80             # tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
-       rol     \$8,`&LO("$acc0")`      # ROTATE(tp1^tp8,8)
-       xor     $tp48,$tp88             # tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
-
-       rol     \$8,`&LO("$acc8")`      # ROTATE(tp1^tp8,8)
-       xor     `&LO("$tp80")`,`&LO("$tp10")`
-       shr     \$32,$tp80
-       xor     `&LO("$tp88")`,`&LO("$tp18")`
-       shr     \$32,$tp88
-       xor     `&LO("$tp80")`,`&LO("$acc0")`
-       xor     `&LO("$tp88")`,`&LO("$acc8")`
-
-       mov     $tp20,$tp80
-       rol     \$24,`&LO("$tp20")`     # ROTATE(tp2^tp1^tp8,24)
-       mov     $tp28,$tp88
-       rol     \$24,`&LO("$tp28")`     # ROTATE(tp2^tp1^tp8,24)
-       shr     \$32,$tp80
-       xor     `&LO("$tp20")`,`&LO("$tp10")`
-       shr     \$32,$tp88
-       xor     `&LO("$tp28")`,`&LO("$tp18")`
-       rol     \$24,`&LO("$tp80")`     # ROTATE(tp2^tp1^tp8,24)
-       mov     $tp40,$tp20
-       rol     \$24,`&LO("$tp88")`     # ROTATE(tp2^tp1^tp8,24)
-       mov     $tp48,$tp28
-       shr     \$32,$tp20
-       xor     `&LO("$tp80")`,`&LO("$acc0")`
-       shr     \$32,$tp28
-       xor     `&LO("$tp88")`,`&LO("$acc8")`
-
-       `"mov   0($sbox),$mask80"       if ($prefetch)`
-       rol     \$16,`&LO("$tp40")`     # ROTATE(tp4^tp1^tp8,16)
-       `"mov   64($sbox),$maskfe"      if ($prefetch)`
-       rol     \$16,`&LO("$tp48")`     # ROTATE(tp4^tp1^tp8,16)
-       `"mov   128($sbox),$mask1b"     if ($prefetch)`
-       rol     \$16,`&LO("$tp20")`     # ROTATE(tp4^tp1^tp8,16)
-       `"mov   192($sbox),$tp80"       if ($prefetch)`
-       xor     `&LO("$tp40")`,`&LO("$tp10")`
-       rol     \$16,`&LO("$tp28")`     # ROTATE(tp4^tp1^tp8,16)
-       xor     `&LO("$tp48")`,`&LO("$tp18")`
-       `"mov   256($sbox),$tp88"       if ($prefetch)`
-       xor     `&LO("$tp20")`,`&LO("$acc0")`
-       xor     `&LO("$tp28")`,`&LO("$acc8")`
-___
-}
-
-$code.=<<___;
-.type  _x86_64_AES_decrypt_compact,\@abi-omnipotent
-.align 16
-_x86_64_AES_decrypt_compact:
-.cfi_startproc
-       lea     128($sbox),$inp                 # size optimization
-       mov     0-128($inp),$acc1               # prefetch Td4
-       mov     32-128($inp),$acc2
-       mov     64-128($inp),$t0
-       mov     96-128($inp),$t1
-       mov     128-128($inp),$acc1
-       mov     160-128($inp),$acc2
-       mov     192-128($inp),$t0
-       mov     224-128($inp),$t1
-       jmp     .Ldec_loop_compact
-
-.align 16
-.Ldec_loop_compact:
-               xor     0($key),$s0             # xor with key
-               xor     4($key),$s1
-               xor     8($key),$s2
-               xor     12($key),$s3
-               lea     16($key),$key
-___
-               &deccompactvert();
-$code.=<<___;
-               cmp     16(%rsp),$key
-               je      .Ldec_compact_done
-
-               mov     256+0($sbox),$mask80
-               shl     \$32,%rbx
-               shl     \$32,%rdx
-               mov     256+8($sbox),$maskfe
-               or      %rbx,%rax
-               or      %rdx,%rcx
-               mov     256+16($sbox),$mask1b
-___
-               &dectransform(1);
-$code.=<<___;
-       jmp     .Ldec_loop_compact
-.align 16
-.Ldec_compact_done:
-       xor     0($key),$s0
-       xor     4($key),$s1
-       xor     8($key),$s2
-       xor     12($key),$s3
-       .byte   0xf3,0xc3                       # rep ret
-.cfi_endproc
-.size  _x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
-___
-
-# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
-$code.=<<___;
-.globl AES_decrypt
-.type  AES_decrypt,\@function,3
-.align 16
-.globl asm_AES_decrypt
-.hidden        asm_AES_decrypt
-asm_AES_decrypt:
-AES_decrypt:
-.cfi_startproc
-       mov     %rsp,%rax
-.cfi_def_cfa_register  %rax
-       push    %rbx
-.cfi_push      %rbx
-       push    %rbp
-.cfi_push      %rbp
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-
-       # allocate frame "above" key schedule
-       lea     -63(%rdx),%rcx  # %rdx is key argument
-       and     \$-64,%rsp
-       sub     %rsp,%rcx
-       neg     %rcx
-       and     \$0x3c0,%rcx
-       sub     %rcx,%rsp
-       sub     \$32,%rsp
-
-       mov     %rsi,16(%rsp)   # save out
-       mov     %rax,24(%rsp)   # save original stack pointer
-.cfi_cfa_expression    %rsp+24,deref,+8
-.Ldec_prologue:
-
-       mov     %rdx,$key
-       mov     240($key),$rnds # load rounds
-
-       mov     0(%rdi),$s0     # load input vector
-       mov     4(%rdi),$s1
-       mov     8(%rdi),$s2
-       mov     12(%rdi),$s3
-
-       shl     \$4,$rnds
-       lea     ($key,$rnds),%rbp
-       mov     $key,(%rsp)     # key schedule
-       mov     %rbp,8(%rsp)    # end of key schedule
-
-       # pick Td4 copy which can't "overlap" with stack frame or key schedule
-       lea     .LAES_Td+2048(%rip),$sbox
-       lea     768(%rsp),%rbp
-       sub     $sbox,%rbp
-       and     \$0x300,%rbp
-       lea     ($sbox,%rbp),$sbox
-       shr     \$3,%rbp        # recall "magic" constants!
-       add     %rbp,$sbox
-
-       call    _x86_64_AES_decrypt_compact
-
-       mov     16(%rsp),$out   # restore out
-       mov     24(%rsp),%rsi   # restore saved stack pointer
-.cfi_def_cfa   %rsi,8
-       mov     $s0,0($out)     # write output vector
-       mov     $s1,4($out)
-       mov     $s2,8($out)
-       mov     $s3,12($out)
-
-       mov     -48(%rsi),%r15
-.cfi_restore   %r15
-       mov     -40(%rsi),%r14
-.cfi_restore   %r14
-       mov     -32(%rsi),%r13
-.cfi_restore   %r13
-       mov     -24(%rsi),%r12
-.cfi_restore   %r12
-       mov     -16(%rsi),%rbp
-.cfi_restore   %rbp
-       mov     -8(%rsi),%rbx
-.cfi_restore   %rbx
-       lea     (%rsi),%rsp
-.cfi_def_cfa_register  %rsp
-.Ldec_epilogue:
-       ret
-.cfi_endproc
-.size  AES_decrypt,.-AES_decrypt
-___
-#------------------------------------------------------------------#
-
-sub enckey()
-{
-$code.=<<___;
-       movz    %dl,%esi                # rk[i]>>0
-       movzb   -128(%rbp,%rsi),%ebx
-       movz    %dh,%esi                # rk[i]>>8
-       shl     \$24,%ebx
-       xor     %ebx,%eax
-
-       movzb   -128(%rbp,%rsi),%ebx
-       shr     \$16,%edx
-       movz    %dl,%esi                # rk[i]>>16
-       xor     %ebx,%eax
-
-       movzb   -128(%rbp,%rsi),%ebx
-       movz    %dh,%esi                # rk[i]>>24
-       shl     \$8,%ebx
-       xor     %ebx,%eax
-
-       movzb   -128(%rbp,%rsi),%ebx
-       shl     \$16,%ebx
-       xor     %ebx,%eax
-
-       xor     1024-128(%rbp,%rcx,4),%eax              # rcon
-___
-}
-
-# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-#                        AES_KEY *key)
-$code.=<<___;
-.globl AES_set_encrypt_key
-.type  AES_set_encrypt_key,\@function,3
-.align 16
-AES_set_encrypt_key:
-.cfi_startproc
-       push    %rbx
-.cfi_push      %rbx
-       push    %rbp
-.cfi_push      %rbp
-       push    %r12                    # redundant, but allows to share
-.cfi_push      %r12
-       push    %r13                    # exception handler...
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-       sub     \$8,%rsp
-.cfi_adjust_cfa_offset 8
-.Lenc_key_prologue:
-
-       call    _x86_64_AES_set_encrypt_key
-
-       mov     40(%rsp),%rbp
-.cfi_restore   %rbp
-       mov     48(%rsp),%rbx
-.cfi_restore   %rbx
-       add     \$56,%rsp
-.cfi_adjust_cfa_offset -56
-.Lenc_key_epilogue:
-       ret
-.cfi_endproc
-.size  AES_set_encrypt_key,.-AES_set_encrypt_key
-
-.type  _x86_64_AES_set_encrypt_key,\@abi-omnipotent
-.align 16
-_x86_64_AES_set_encrypt_key:
-.cfi_startproc
-       mov     %esi,%ecx                       # %ecx=bits
-       mov     %rdi,%rsi                       # %rsi=userKey
-       mov     %rdx,%rdi                       # %rdi=key
-
-       test    \$-1,%rsi
-       jz      .Lbadpointer
-       test    \$-1,%rdi
-       jz      .Lbadpointer
-
-       lea     .LAES_Te(%rip),%rbp
-       lea     2048+128(%rbp),%rbp
-
-       # prefetch Te4
-       mov     0-128(%rbp),%eax
-       mov     32-128(%rbp),%ebx
-       mov     64-128(%rbp),%r8d
-       mov     96-128(%rbp),%edx
-       mov     128-128(%rbp),%eax
-       mov     160-128(%rbp),%ebx
-       mov     192-128(%rbp),%r8d
-       mov     224-128(%rbp),%edx
-
-       cmp     \$128,%ecx
-       je      .L10rounds
-       cmp     \$192,%ecx
-       je      .L12rounds
-       cmp     \$256,%ecx
-       je      .L14rounds
-       mov     \$-2,%rax                       # invalid number of bits
-       jmp     .Lexit
-
-.L10rounds:
-       mov     0(%rsi),%rax                    # copy first 4 dwords
-       mov     8(%rsi),%rdx
-       mov     %rax,0(%rdi)
-       mov     %rdx,8(%rdi)
-
-       shr     \$32,%rdx
-       xor     %ecx,%ecx
-       jmp     .L10shortcut
-.align 4
-.L10loop:
-               mov     0(%rdi),%eax                    # rk[0]
-               mov     12(%rdi),%edx                   # rk[3]
-.L10shortcut:
-___
-               &enckey ();
-$code.=<<___;
-               mov     %eax,16(%rdi)                   # rk[4]
-               xor     4(%rdi),%eax
-               mov     %eax,20(%rdi)                   # rk[5]
-               xor     8(%rdi),%eax
-               mov     %eax,24(%rdi)                   # rk[6]
-               xor     12(%rdi),%eax
-               mov     %eax,28(%rdi)                   # rk[7]
-               add     \$1,%ecx
-               lea     16(%rdi),%rdi
-               cmp     \$10,%ecx
-       jl      .L10loop
-
-       movl    \$10,80(%rdi)                   # setup number of rounds
-       xor     %rax,%rax
-       jmp     .Lexit
-
-.L12rounds:
-       mov     0(%rsi),%rax                    # copy first 6 dwords
-       mov     8(%rsi),%rbx
-       mov     16(%rsi),%rdx
-       mov     %rax,0(%rdi)
-       mov     %rbx,8(%rdi)
-       mov     %rdx,16(%rdi)
-
-       shr     \$32,%rdx
-       xor     %ecx,%ecx
-       jmp     .L12shortcut
-.align 4
-.L12loop:
-               mov     0(%rdi),%eax                    # rk[0]
-               mov     20(%rdi),%edx                   # rk[5]
-.L12shortcut:
-___
-               &enckey ();
-$code.=<<___;
-               mov     %eax,24(%rdi)                   # rk[6]
-               xor     4(%rdi),%eax
-               mov     %eax,28(%rdi)                   # rk[7]
-               xor     8(%rdi),%eax
-               mov     %eax,32(%rdi)                   # rk[8]
-               xor     12(%rdi),%eax
-               mov     %eax,36(%rdi)                   # rk[9]
-
-               cmp     \$7,%ecx
-               je      .L12break
-               add     \$1,%ecx
-
-               xor     16(%rdi),%eax
-               mov     %eax,40(%rdi)                   # rk[10]
-               xor     20(%rdi),%eax
-               mov     %eax,44(%rdi)                   # rk[11]
-
-               lea     24(%rdi),%rdi
-       jmp     .L12loop
-.L12break:
-       movl    \$12,72(%rdi)           # setup number of rounds
-       xor     %rax,%rax
-       jmp     .Lexit
-
-.L14rounds:
-       mov     0(%rsi),%rax                    # copy first 8 dwords
-       mov     8(%rsi),%rbx
-       mov     16(%rsi),%rcx
-       mov     24(%rsi),%rdx
-       mov     %rax,0(%rdi)
-       mov     %rbx,8(%rdi)
-       mov     %rcx,16(%rdi)
-       mov     %rdx,24(%rdi)
-
-       shr     \$32,%rdx
-       xor     %ecx,%ecx
-       jmp     .L14shortcut
-.align 4
-.L14loop:
-               mov     0(%rdi),%eax                    # rk[0]
-               mov     28(%rdi),%edx                   # rk[4]
-.L14shortcut:
-___
-               &enckey ();
-$code.=<<___;
-               mov     %eax,32(%rdi)                   # rk[8]
-               xor     4(%rdi),%eax
-               mov     %eax,36(%rdi)                   # rk[9]
-               xor     8(%rdi),%eax
-               mov     %eax,40(%rdi)                   # rk[10]
-               xor     12(%rdi),%eax
-               mov     %eax,44(%rdi)                   # rk[11]
-
-               cmp     \$6,%ecx
-               je      .L14break
-               add     \$1,%ecx
-
-               mov     %eax,%edx
-               mov     16(%rdi),%eax                   # rk[4]
-               movz    %dl,%esi                        # rk[11]>>0
-               movzb   -128(%rbp,%rsi),%ebx
-               movz    %dh,%esi                        # rk[11]>>8
-               xor     %ebx,%eax
-
-               movzb   -128(%rbp,%rsi),%ebx
-               shr     \$16,%edx
-               shl     \$8,%ebx
-               movz    %dl,%esi                        # rk[11]>>16
-               xor     %ebx,%eax
-
-               movzb   -128(%rbp,%rsi),%ebx
-               movz    %dh,%esi                        # rk[11]>>24
-               shl     \$16,%ebx
-               xor     %ebx,%eax
-
-               movzb   -128(%rbp,%rsi),%ebx
-               shl     \$24,%ebx
-               xor     %ebx,%eax
-
-               mov     %eax,48(%rdi)                   # rk[12]
-               xor     20(%rdi),%eax
-               mov     %eax,52(%rdi)                   # rk[13]
-               xor     24(%rdi),%eax
-               mov     %eax,56(%rdi)                   # rk[14]
-               xor     28(%rdi),%eax
-               mov     %eax,60(%rdi)                   # rk[15]
-
-               lea     32(%rdi),%rdi
-       jmp     .L14loop
-.L14break:
-       movl    \$14,48(%rdi)           # setup number of rounds
-       xor     %rax,%rax
-       jmp     .Lexit
-
-.Lbadpointer:
-       mov     \$-1,%rax
-.Lexit:
-       .byte   0xf3,0xc3                       # rep ret
-.cfi_endproc
-.size  _x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
-___
-
-sub deckey_ref()
-{ my ($i,$ptr,$te,$td) = @_;
-  my ($tp1,$tp2,$tp4,$tp8,$acc)=("%eax","%ebx","%edi","%edx","%r8d");
-$code.=<<___;
-       mov     $i($ptr),$tp1
-       mov     $tp1,$acc
-       and     \$0x80808080,$acc
-       mov     $acc,$tp4
-       shr     \$7,$tp4
-       lea     0($tp1,$tp1),$tp2
-       sub     $tp4,$acc
-       and     \$0xfefefefe,$tp2
-       and     \$0x1b1b1b1b,$acc
-       xor     $tp2,$acc
-       mov     $acc,$tp2
-
-       and     \$0x80808080,$acc
-       mov     $acc,$tp8
-       shr     \$7,$tp8
-       lea     0($tp2,$tp2),$tp4
-       sub     $tp8,$acc
-       and     \$0xfefefefe,$tp4
-       and     \$0x1b1b1b1b,$acc
-        xor    $tp1,$tp2               # tp2^tp1
-       xor     $tp4,$acc
-       mov     $acc,$tp4
-
-       and     \$0x80808080,$acc
-       mov     $acc,$tp8
-       shr     \$7,$tp8
-       sub     $tp8,$acc
-       lea     0($tp4,$tp4),$tp8
-        xor    $tp1,$tp4               # tp4^tp1
-       and     \$0xfefefefe,$tp8
-       and     \$0x1b1b1b1b,$acc
-       xor     $acc,$tp8
-
-       xor     $tp8,$tp1               # tp1^tp8
-       rol     \$8,$tp1                # ROTATE(tp1^tp8,8)
-       xor     $tp8,$tp2               # tp2^tp1^tp8
-       xor     $tp8,$tp4               # tp4^tp1^tp8
-       xor     $tp2,$tp8
-       xor     $tp4,$tp8               # tp8^(tp8^tp4^tp1)^(tp8^tp2^tp1)=tp8^tp4^tp2
-
-       xor     $tp8,$tp1
-       rol     \$24,$tp2               # ROTATE(tp2^tp1^tp8,24)
-       xor     $tp2,$tp1
-       rol     \$16,$tp4               # ROTATE(tp4^tp1^tp8,16)
-       xor     $tp4,$tp1
-
-       mov     $tp1,$i($ptr)
-___
-}
-
-# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
-#                        AES_KEY *key)
-$code.=<<___;
-.globl AES_set_decrypt_key
-.type  AES_set_decrypt_key,\@function,3
-.align 16
-AES_set_decrypt_key:
-.cfi_startproc
-       push    %rbx
-.cfi_push      %rbx
-       push    %rbp
-.cfi_push      %rbp
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-       push    %rdx                    # save key schedule
-.cfi_adjust_cfa_offset 8
-.Ldec_key_prologue:
-
-       call    _x86_64_AES_set_encrypt_key
-       mov     (%rsp),%r8              # restore key schedule
-       cmp     \$0,%eax
-       jne     .Labort
-
-       mov     240(%r8),%r14d          # pull number of rounds
-       xor     %rdi,%rdi
-       lea     (%rdi,%r14d,4),%rcx
-       mov     %r8,%rsi
-       lea     (%r8,%rcx,4),%rdi       # pointer to last chunk
-.align 4
-.Linvert:
-               mov     0(%rsi),%rax
-               mov     8(%rsi),%rbx
-               mov     0(%rdi),%rcx
-               mov     8(%rdi),%rdx
-               mov     %rax,0(%rdi)
-               mov     %rbx,8(%rdi)
-               mov     %rcx,0(%rsi)
-               mov     %rdx,8(%rsi)
-               lea     16(%rsi),%rsi
-               lea     -16(%rdi),%rdi
-               cmp     %rsi,%rdi
-       jne     .Linvert
-
-       lea     .LAES_Te+2048+1024(%rip),%rax   # rcon
-
-       mov     40(%rax),$mask80
-       mov     48(%rax),$maskfe
-       mov     56(%rax),$mask1b
-
-       mov     %r8,$key
-       sub     \$1,%r14d
-.align 4
-.Lpermute:
-               lea     16($key),$key
-               mov     0($key),%rax
-               mov     8($key),%rcx
-___
-               &dectransform ();
-$code.=<<___;
-               mov     %eax,0($key)
-               mov     %ebx,4($key)
-               mov     %ecx,8($key)
-               mov     %edx,12($key)
-               sub     \$1,%r14d
-       jnz     .Lpermute
-
-       xor     %rax,%rax
-.Labort:
-       mov     8(%rsp),%r15
-.cfi_restore   %r15
-       mov     16(%rsp),%r14
-.cfi_restore   %r14
-       mov     24(%rsp),%r13
-.cfi_restore   %r13
-       mov     32(%rsp),%r12
-.cfi_restore   %r12
-       mov     40(%rsp),%rbp
-.cfi_restore   %rbp
-       mov     48(%rsp),%rbx
-.cfi_restore   %rbx
-       add     \$56,%rsp
-.cfi_adjust_cfa_offset -56
-.Ldec_key_epilogue:
-       ret
-.cfi_endproc
-.size  AES_set_decrypt_key,.-AES_set_decrypt_key
-___
-
-# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
-#                      size_t length, const AES_KEY *key,
-#                      unsigned char *ivp,const int enc);
-{
-# stack frame layout
-# -8(%rsp)             return address
-my $keyp="0(%rsp)";            # one to pass as $key
-my $keyend="8(%rsp)";          # &(keyp->rd_key[4*keyp->rounds])
-my $_rsp="16(%rsp)";           # saved %rsp
-my $_inp="24(%rsp)";           # copy of 1st parameter, inp
-my $_out="32(%rsp)";           # copy of 2nd parameter, out
-my $_len="40(%rsp)";           # copy of 3rd parameter, length
-my $_key="48(%rsp)";           # copy of 4th parameter, key
-my $_ivp="56(%rsp)";           # copy of 5th parameter, ivp
-my $ivec="64(%rsp)";           # ivec[16]
-my $aes_key="80(%rsp)";                # copy of aes_key
-my $mark="80+240(%rsp)";       # copy of aes_key->rounds
-
-$code.=<<___;
-.globl AES_cbc_encrypt
-.type  AES_cbc_encrypt,\@function,6
-.align 16
-.extern        OPENSSL_ia32cap_P
-.globl asm_AES_cbc_encrypt
-.hidden        asm_AES_cbc_encrypt
-asm_AES_cbc_encrypt:
-AES_cbc_encrypt:
-.cfi_startproc
-       cmp     \$0,%rdx        # check length
-       je      .Lcbc_epilogue
-       pushfq
-# This could be .cfi_push 49, but libunwind fails on registers it does not
-# recognize. See https://bugzilla.redhat.com/show_bug.cgi?id=217087.
-.cfi_adjust_cfa_offset 8
-       push    %rbx
-.cfi_push      %rbx
-       push    %rbp
-.cfi_push      %rbp
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-.Lcbc_prologue:
-
-       cld
-       mov     %r9d,%r9d       # clear upper half of enc
-
-       lea     .LAES_Te(%rip),$sbox
-       lea     .LAES_Td(%rip),%r10
-       cmp     \$0,%r9
-       cmoveq  %r10,$sbox
-
-.cfi_remember_state
-       mov     OPENSSL_ia32cap_P(%rip),%r10d
-       cmp     \$$speed_limit,%rdx
-       jb      .Lcbc_slow_prologue
-       test    \$15,%rdx
-       jnz     .Lcbc_slow_prologue
-       bt      \$28,%r10d
-       jc      .Lcbc_slow_prologue
-
-       # allocate aligned stack frame...
-       lea     -88-248(%rsp),$key
-       and     \$-64,$key
-
-       # ... and make sure it doesn't alias with AES_T[ed] modulo 4096
-       mov     $sbox,%r10
-       lea     2304($sbox),%r11
-       mov     $key,%r12
-       and     \$0xFFF,%r10    # s = $sbox&0xfff
-       and     \$0xFFF,%r11    # e = ($sbox+2048)&0xfff
-       and     \$0xFFF,%r12    # p = %rsp&0xfff
-
-       cmp     %r11,%r12       # if (p=>e) %rsp =- (p-e);
-       jb      .Lcbc_te_break_out
-       sub     %r11,%r12
-       sub     %r12,$key
-       jmp     .Lcbc_te_ok
-.Lcbc_te_break_out:            # else %rsp -= (p-s)&0xfff + framesz
-       sub     %r10,%r12
-       and     \$0xFFF,%r12
-       add     \$320,%r12
-       sub     %r12,$key
-.align 4
-.Lcbc_te_ok:
-
-       xchg    %rsp,$key
-.cfi_def_cfa_register  $key
-       #add    \$8,%rsp        # reserve for return address!
-       mov     $key,$_rsp      # save %rsp
-.cfi_cfa_expression    $_rsp,deref,+64
-.Lcbc_fast_body:
-       mov     %rdi,$_inp      # save copy of inp
-       mov     %rsi,$_out      # save copy of out
-       mov     %rdx,$_len      # save copy of len
-       mov     %rcx,$_key      # save copy of key
-       mov     %r8,$_ivp       # save copy of ivp
-       movl    \$0,$mark       # copy of aes_key->rounds = 0;
-       mov     %r8,%rbp        # rearrange input arguments
-       mov     %r9,%rbx
-       mov     %rsi,$out
-       mov     %rdi,$inp
-       mov     %rcx,$key
-
-       mov     240($key),%eax          # key->rounds
-       # do we copy key schedule to stack?
-       mov     $key,%r10
-       sub     $sbox,%r10
-       and     \$0xfff,%r10
-       cmp     \$2304,%r10
-       jb      .Lcbc_do_ecopy
-       cmp     \$4096-248,%r10
-       jb      .Lcbc_skip_ecopy
-.align 4
-.Lcbc_do_ecopy:
-               mov     $key,%rsi
-               lea     $aes_key,%rdi
-               lea     $aes_key,$key
-               mov     \$240/8,%ecx
-               .long   0x90A548F3      # rep movsq
-               mov     %eax,(%rdi)     # copy aes_key->rounds
-.Lcbc_skip_ecopy:
-       mov     $key,$keyp      # save key pointer
-
-       mov     \$18,%ecx
-.align 4
-.Lcbc_prefetch_te:
-               mov     0($sbox),%r10
-               mov     32($sbox),%r11
-               mov     64($sbox),%r12
-               mov     96($sbox),%r13
-               lea     128($sbox),$sbox
-               sub     \$1,%ecx
-       jnz     .Lcbc_prefetch_te
-       lea     -2304($sbox),$sbox
-
-       cmp     \$0,%rbx
-       je      .LFAST_DECRYPT
-
-#----------------------------- ENCRYPT -----------------------------#
-       mov     0(%rbp),$s0             # load iv
-       mov     4(%rbp),$s1
-       mov     8(%rbp),$s2
-       mov     12(%rbp),$s3
-
-.align 4
-.Lcbc_fast_enc_loop:
-               xor     0($inp),$s0
-               xor     4($inp),$s1
-               xor     8($inp),$s2
-               xor     12($inp),$s3
-               mov     $keyp,$key      # restore key
-               mov     $inp,$_inp      # if ($verticalspin) save inp
-
-               call    _x86_64_AES_encrypt
-
-               mov     $_inp,$inp      # if ($verticalspin) restore inp
-               mov     $_len,%r10
-               mov     $s0,0($out)
-               mov     $s1,4($out)
-               mov     $s2,8($out)
-               mov     $s3,12($out)
-
-               lea     16($inp),$inp
-               lea     16($out),$out
-               sub     \$16,%r10
-               test    \$-16,%r10
-               mov     %r10,$_len
-       jnz     .Lcbc_fast_enc_loop
-       mov     $_ivp,%rbp      # restore ivp
-       mov     $s0,0(%rbp)     # save ivec
-       mov     $s1,4(%rbp)
-       mov     $s2,8(%rbp)
-       mov     $s3,12(%rbp)
-
-       jmp     .Lcbc_fast_cleanup
-
-#----------------------------- DECRYPT -----------------------------#
-.align 16
-.LFAST_DECRYPT:
-       cmp     $inp,$out
-       je      .Lcbc_fast_dec_in_place
-
-       mov     %rbp,$ivec
-.align 4
-.Lcbc_fast_dec_loop:
-               mov     0($inp),$s0     # read input
-               mov     4($inp),$s1
-               mov     8($inp),$s2
-               mov     12($inp),$s3
-               mov     $keyp,$key      # restore key
-               mov     $inp,$_inp      # if ($verticalspin) save inp
-
-               call    _x86_64_AES_decrypt
-
-               mov     $ivec,%rbp      # load ivp
-               mov     $_inp,$inp      # if ($verticalspin) restore inp
-               mov     $_len,%r10      # load len
-               xor     0(%rbp),$s0     # xor iv
-               xor     4(%rbp),$s1
-               xor     8(%rbp),$s2
-               xor     12(%rbp),$s3
-               mov     $inp,%rbp       # current input, next iv
-
-               sub     \$16,%r10
-               mov     %r10,$_len      # update len
-               mov     %rbp,$ivec      # update ivp
-
-               mov     $s0,0($out)     # write output
-               mov     $s1,4($out)
-               mov     $s2,8($out)
-               mov     $s3,12($out)
-
-               lea     16($inp),$inp
-               lea     16($out),$out
-       jnz     .Lcbc_fast_dec_loop
-       mov     $_ivp,%r12              # load user ivp
-       mov     0(%rbp),%r10            # load iv
-       mov     8(%rbp),%r11
-       mov     %r10,0(%r12)            # copy back to user
-       mov     %r11,8(%r12)
-       jmp     .Lcbc_fast_cleanup
-
-.align 16
-.Lcbc_fast_dec_in_place:
-       mov     0(%rbp),%r10            # copy iv to stack
-       mov     8(%rbp),%r11
-       mov     %r10,0+$ivec
-       mov     %r11,8+$ivec
-.align 4
-.Lcbc_fast_dec_in_place_loop:
-               mov     0($inp),$s0     # load input
-               mov     4($inp),$s1
-               mov     8($inp),$s2
-               mov     12($inp),$s3
-               mov     $keyp,$key      # restore key
-               mov     $inp,$_inp      # if ($verticalspin) save inp
-
-               call    _x86_64_AES_decrypt
-
-               mov     $_inp,$inp      # if ($verticalspin) restore inp
-               mov     $_len,%r10
-               xor     0+$ivec,$s0
-               xor     4+$ivec,$s1
-               xor     8+$ivec,$s2
-               xor     12+$ivec,$s3
-
-               mov     0($inp),%r11    # load input
-               mov     8($inp),%r12
-               sub     \$16,%r10
-               jz      .Lcbc_fast_dec_in_place_done
-
-               mov     %r11,0+$ivec    # copy input to iv
-               mov     %r12,8+$ivec
-
-               mov     $s0,0($out)     # save output [zaps input]
-               mov     $s1,4($out)
-               mov     $s2,8($out)
-               mov     $s3,12($out)
-
-               lea     16($inp),$inp
-               lea     16($out),$out
-               mov     %r10,$_len
-       jmp     .Lcbc_fast_dec_in_place_loop
-.Lcbc_fast_dec_in_place_done:
-       mov     $_ivp,%rdi
-       mov     %r11,0(%rdi)    # copy iv back to user
-       mov     %r12,8(%rdi)
-
-       mov     $s0,0($out)     # save output [zaps input]
-       mov     $s1,4($out)
-       mov     $s2,8($out)
-       mov     $s3,12($out)
-
-.align 4
-.Lcbc_fast_cleanup:
-       cmpl    \$0,$mark       # was the key schedule copied?
-       lea     $aes_key,%rdi
-       je      .Lcbc_exit
-               mov     \$240/8,%ecx
-               xor     %rax,%rax
-               .long   0x90AB48F3      # rep stosq
-
-       jmp     .Lcbc_exit
-
-#--------------------------- SLOW ROUTINE ---------------------------#
-.align 16
-.Lcbc_slow_prologue:
-.cfi_restore_state
-       # allocate aligned stack frame...
-       lea     -88(%rsp),%rbp
-       and     \$-64,%rbp
-       # ... just "above" key schedule
-       lea     -88-63(%rcx),%r10
-       sub     %rbp,%r10
-       neg     %r10
-       and     \$0x3c0,%r10
-       sub     %r10,%rbp
-
-       xchg    %rsp,%rbp
-.cfi_def_cfa_register  %rbp
-       #add    \$8,%rsp        # reserve for return address!
-       mov     %rbp,$_rsp      # save %rsp
-.cfi_cfa_expression    $_rsp,deref,+64
-.Lcbc_slow_body:
-       #mov    %rdi,$_inp      # save copy of inp
-       #mov    %rsi,$_out      # save copy of out
-       #mov    %rdx,$_len      # save copy of len
-       #mov    %rcx,$_key      # save copy of key
-       mov     %r8,$_ivp       # save copy of ivp
-       mov     %r8,%rbp        # rearrange input arguments
-       mov     %r9,%rbx
-       mov     %rsi,$out
-       mov     %rdi,$inp
-       mov     %rcx,$key
-       mov     %rdx,%r10
-
-       mov     240($key),%eax
-       mov     $key,$keyp      # save key pointer
-       shl     \$4,%eax
-       lea     ($key,%rax),%rax
-       mov     %rax,$keyend
-
-       # pick Te4 copy which can't "overlap" with stack frame or key schedule
-       lea     2048($sbox),$sbox
-       lea     768-8(%rsp),%rax
-       sub     $sbox,%rax
-       and     \$0x300,%rax
-       lea     ($sbox,%rax),$sbox
-
-       cmp     \$0,%rbx
-       je      .LSLOW_DECRYPT
-
-#--------------------------- SLOW ENCRYPT ---------------------------#
-       test    \$-16,%r10              # check upon length
-       mov     0(%rbp),$s0             # load iv
-       mov     4(%rbp),$s1
-       mov     8(%rbp),$s2
-       mov     12(%rbp),$s3
-       jz      .Lcbc_slow_enc_tail     # short input...
-
-.align 4
-.Lcbc_slow_enc_loop:
-               xor     0($inp),$s0
-               xor     4($inp),$s1
-               xor     8($inp),$s2
-               xor     12($inp),$s3
-               mov     $keyp,$key      # restore key
-               mov     $inp,$_inp      # save inp
-               mov     $out,$_out      # save out
-               mov     %r10,$_len      # save len
-
-               call    _x86_64_AES_encrypt_compact
-
-               mov     $_inp,$inp      # restore inp
-               mov     $_out,$out      # restore out
-               mov     $_len,%r10      # restore len
-               mov     $s0,0($out)
-               mov     $s1,4($out)
-               mov     $s2,8($out)
-               mov     $s3,12($out)
-
-               lea     16($inp),$inp
-               lea     16($out),$out
-               sub     \$16,%r10
-               test    \$-16,%r10
-       jnz     .Lcbc_slow_enc_loop
-       test    \$15,%r10
-       jnz     .Lcbc_slow_enc_tail
-       mov     $_ivp,%rbp      # restore ivp
-       mov     $s0,0(%rbp)     # save ivec
-       mov     $s1,4(%rbp)
-       mov     $s2,8(%rbp)
-       mov     $s3,12(%rbp)
-
-       jmp     .Lcbc_exit
-
-.align 4
-.Lcbc_slow_enc_tail:
-       mov     %rax,%r11
-       mov     %rcx,%r12
-       mov     %r10,%rcx
-       mov     $inp,%rsi
-       mov     $out,%rdi
-       .long   0x9066A4F3              # rep movsb
-       mov     \$16,%rcx               # zero tail
-       sub     %r10,%rcx
-       xor     %rax,%rax
-       .long   0x9066AAF3              # rep stosb
-       mov     $out,$inp               # this is not a mistake!
-       mov     \$16,%r10               # len=16
-       mov     %r11,%rax
-       mov     %r12,%rcx
-       jmp     .Lcbc_slow_enc_loop     # one more spin...
-#--------------------------- SLOW DECRYPT ---------------------------#
-.align 16
-.LSLOW_DECRYPT:
-       shr     \$3,%rax
-       add     %rax,$sbox              # recall "magic" constants!
-
-       mov     0(%rbp),%r11            # copy iv to stack
-       mov     8(%rbp),%r12
-       mov     %r11,0+$ivec
-       mov     %r12,8+$ivec
-
-.align 4
-.Lcbc_slow_dec_loop:
-               mov     0($inp),$s0     # load input
-               mov     4($inp),$s1
-               mov     8($inp),$s2
-               mov     12($inp),$s3
-               mov     $keyp,$key      # restore key
-               mov     $inp,$_inp      # save inp
-               mov     $out,$_out      # save out
-               mov     %r10,$_len      # save len
-
-               call    _x86_64_AES_decrypt_compact
-
-               mov     $_inp,$inp      # restore inp
-               mov     $_out,$out      # restore out
-               mov     $_len,%r10
-               xor     0+$ivec,$s0
-               xor     4+$ivec,$s1
-               xor     8+$ivec,$s2
-               xor     12+$ivec,$s3
-
-               mov     0($inp),%r11    # load input
-               mov     8($inp),%r12
-               sub     \$16,%r10
-               jc      .Lcbc_slow_dec_partial
-               jz      .Lcbc_slow_dec_done
-
-               mov     %r11,0+$ivec    # copy input to iv
-               mov     %r12,8+$ivec
-
-               mov     $s0,0($out)     # save output [can zap input]
-               mov     $s1,4($out)
-               mov     $s2,8($out)
-               mov     $s3,12($out)
-
-               lea     16($inp),$inp
-               lea     16($out),$out
-       jmp     .Lcbc_slow_dec_loop
-.Lcbc_slow_dec_done:
-       mov     $_ivp,%rdi
-       mov     %r11,0(%rdi)            # copy iv back to user
-       mov     %r12,8(%rdi)
-
-       mov     $s0,0($out)             # save output [can zap input]
-       mov     $s1,4($out)
-       mov     $s2,8($out)
-       mov     $s3,12($out)
-
-       jmp     .Lcbc_exit
-
-.align 4
-.Lcbc_slow_dec_partial:
-       mov     $_ivp,%rdi
-       mov     %r11,0(%rdi)            # copy iv back to user
-       mov     %r12,8(%rdi)
-
-       mov     $s0,0+$ivec             # save output to stack
-       mov     $s1,4+$ivec
-       mov     $s2,8+$ivec
-       mov     $s3,12+$ivec
-
-       mov     $out,%rdi
-       lea     $ivec,%rsi
-       lea     16(%r10),%rcx
-       .long   0x9066A4F3      # rep movsb
-       jmp     .Lcbc_exit
-
-.align 16
-.Lcbc_exit:
-       mov     $_rsp,%rsi
-.cfi_def_cfa   %rsi,64
-       mov     (%rsi),%r15
-.cfi_restore   %r15
-       mov     8(%rsi),%r14
-.cfi_restore   %r14
-       mov     16(%rsi),%r13
-.cfi_restore   %r13
-       mov     24(%rsi),%r12
-.cfi_restore   %r12
-       mov     32(%rsi),%rbp
-.cfi_restore   %rbp
-       mov     40(%rsi),%rbx
-.cfi_restore   %rbx
-       lea     48(%rsi),%rsp
-.cfi_def_cfa   %rsp,16
-.Lcbc_popfq:
-       popfq
-# This could be .cfi_pop 49, but libunwind fails on registers it does not
-# recognize. See https://bugzilla.redhat.com/show_bug.cgi?id=217087.
-.cfi_adjust_cfa_offset -8
-.Lcbc_epilogue:
-       ret
-.cfi_endproc
-.size  AES_cbc_encrypt,.-AES_cbc_encrypt
-___
-}
-
-$code.=<<___;
-.align 64
-.LAES_Te:
-___
-       &_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
-       &_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
-       &_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56);
-       &_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec);
-       &_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa);
-       &_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb);
-       &_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45);
-       &_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b);
-       &_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c);
-       &_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83);
-       &_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9);
-       &_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a);
-       &_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d);
-       &_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f);
-       &_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df);
-       &_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea);
-       &_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34);
-       &_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b);
-       &_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d);
-       &_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413);
-       &_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1);
-       &_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6);
-       &_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972);
-       &_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85);
-       &_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed);
-       &_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511);
-       &_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe);
-       &_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b);
-       &_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05);
-       &_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1);
-       &_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142);
-       &_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf);
-       &_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3);
-       &_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e);
-       &_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a);
-       &_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6);
-       &_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3);
-       &_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b);
-       &_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428);
-       &_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad);
-       &_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14);
-       &_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8);
-       &_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4);
-       &_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2);
-       &_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda);
-       &_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949);
-       &_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf);
-       &_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810);
-       &_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c);
-       &_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697);
-       &_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e);
-       &_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f);
-       &_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc);
-       &_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c);
-       &_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969);
-       &_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27);
-       &_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122);
-       &_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433);
-       &_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9);
-       &_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5);
-       &_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a);
-       &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
-       &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
-       &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
-
-#Te4   # four copies of Te4 to choose from to avoid L1 aliasing
-       &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-       &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-       &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-       &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-       &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-       &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-       &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-       &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-       &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-       &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-       &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-       &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-       &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-       &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-       &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-       &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-       &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-       &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-       &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-       &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-       &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-       &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-       &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-       &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-       &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-       &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-       &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-       &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-       &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-       &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-       &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-       &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-
-       &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-       &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-       &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-       &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-       &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-       &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-       &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-       &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-       &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-       &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-       &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-       &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-       &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-       &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-       &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-       &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-       &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-       &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-       &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-       &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-       &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-       &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-       &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-       &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-       &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-       &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-       &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-       &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-       &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-       &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-       &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-       &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-
-       &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-       &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-       &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-       &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-       &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-       &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-       &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-       &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-       &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-       &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-       &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-       &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-       &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-       &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-       &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-       &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-       &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-       &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-       &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-       &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-       &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-       &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-       &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-       &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-       &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-       &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-       &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-       &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-       &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-       &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-       &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-       &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-
-       &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-       &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-       &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-       &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-       &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-       &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-       &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-       &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-       &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-       &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-       &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-       &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-       &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-       &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-       &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-       &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-       &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-       &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-       &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-       &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-       &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-       &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-       &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-       &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-       &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-       &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-       &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-       &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-       &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-       &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-       &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-       &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-#rcon:
-$code.=<<___;
-       .long   0x00000001, 0x00000002, 0x00000004, 0x00000008
-       .long   0x00000010, 0x00000020, 0x00000040, 0x00000080
-       .long   0x0000001b, 0x00000036, 0x80808080, 0x80808080
-       .long   0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
-___
-$code.=<<___;
-.align 64
-.LAES_Td:
-___
-       &_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
-       &_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
-       &_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5);
-       &_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5);
-       &_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d);
-       &_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b);
-       &_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295);
-       &_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e);
-       &_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927);
-       &_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d);
-       &_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362);
-       &_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9);
-       &_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52);
-       &_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566);
-       &_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3);
-       &_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed);
-       &_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e);
-       &_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4);
-       &_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4);
-       &_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd);
-       &_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d);
-       &_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060);
-       &_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967);
-       &_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879);
-       &_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000);
-       &_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c);
-       &_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36);
-       &_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624);
-       &_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b);
-       &_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c);
-       &_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12);
-       &_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14);
-       &_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3);
-       &_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b);
-       &_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8);
-       &_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684);
-       &_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7);
-       &_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177);
-       &_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947);
-       &_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322);
-       &_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498);
-       &_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f);
-       &_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54);
-       &_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382);
-       &_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf);
-       &_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb);
-       &_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83);
-       &_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef);
-       &_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029);
-       &_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235);
-       &_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733);
-       &_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117);
-       &_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4);
-       &_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546);
-       &_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb);
-       &_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d);
-       &_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb);
-       &_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a);
-       &_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773);
-       &_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478);
-       &_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2);
-       &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
-       &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
-       &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
-
-#Td4:  # four copies of Td4 to choose from to avoid L1 aliasing
-       &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-       &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-       &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-       &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-       &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-       &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-       &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-       &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-       &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-       &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-       &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-       &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-       &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-       &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-       &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-       &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-       &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-       &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-       &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-       &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-       &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-       &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-       &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-       &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-       &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-       &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-       &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-       &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-       &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-       &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-       &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-       &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-$code.=<<___;
-       .long   0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
-       .long   0x1b1b1b1b, 0x1b1b1b1b, 0, 0
-___
-       &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-       &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-       &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-       &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-       &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-       &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-       &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-       &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-       &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-       &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-       &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-       &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-       &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-       &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-       &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-       &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-       &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-       &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-       &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-       &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-       &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-       &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-       &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-       &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-       &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-       &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-       &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-       &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-       &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-       &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-       &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-       &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-$code.=<<___;
-       .long   0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
-       .long   0x1b1b1b1b, 0x1b1b1b1b, 0, 0
-___
-       &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-       &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-       &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-       &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-       &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-       &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-       &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-       &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-       &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-       &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-       &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-       &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-       &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-       &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-       &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-       &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-       &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-       &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-       &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-       &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-       &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-       &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-       &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-       &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-       &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-       &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-       &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-       &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-       &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-       &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-       &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-       &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-$code.=<<___;
-       .long   0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
-       .long   0x1b1b1b1b, 0x1b1b1b1b, 0, 0
-___
-       &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-       &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-       &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-       &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-       &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-       &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-       &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-       &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-       &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-       &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-       &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-       &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-       &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-       &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-       &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-       &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-       &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-       &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-       &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-       &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-       &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-       &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-       &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-       &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-       &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-       &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-       &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-       &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-       &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-       &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-       &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-       &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-$code.=<<___;
-       .long   0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
-       .long   0x1b1b1b1b, 0x1b1b1b1b, 0, 0
-.asciz  "AES for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
-.align 64
-___
-
-# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-#              CONTEXT *context,DISPATCHER_CONTEXT *disp)
-if ($win64) {
-$rec="%rcx";
-$frame="%rdx";
-$context="%r8";
-$disp="%r9";
-
-$code.=<<___;
-.extern        __imp_RtlVirtualUnwind
-.type  block_se_handler,\@abi-omnipotent
-.align 16
-block_se_handler:
-       push    %rsi
-       push    %rdi
-       push    %rbx
-       push    %rbp
-       push    %r12
-       push    %r13
-       push    %r14
-       push    %r15
-       pushfq
-       sub     \$64,%rsp
-
-       mov     120($context),%rax      # pull context->Rax
-       mov     248($context),%rbx      # pull context->Rip
-
-       mov     8($disp),%rsi           # disp->ImageBase
-       mov     56($disp),%r11          # disp->HandlerData
-
-       mov     0(%r11),%r10d           # HandlerData[0]
-       lea     (%rsi,%r10),%r10        # prologue label
-       cmp     %r10,%rbx               # context->Rip<prologue label
-       jb      .Lin_block_prologue
-
-       mov     152($context),%rax      # pull context->Rsp
-
-       mov     4(%r11),%r10d           # HandlerData[1]
-       lea     (%rsi,%r10),%r10        # epilogue label
-       cmp     %r10,%rbx               # context->Rip>=epilogue label
-       jae     .Lin_block_prologue
-
-       mov     24(%rax),%rax           # pull saved real stack pointer
-
-       mov     -8(%rax),%rbx
-       mov     -16(%rax),%rbp
-       mov     -24(%rax),%r12
-       mov     -32(%rax),%r13
-       mov     -40(%rax),%r14
-       mov     -48(%rax),%r15
-       mov     %rbx,144($context)      # restore context->Rbx
-       mov     %rbp,160($context)      # restore context->Rbp
-       mov     %r12,216($context)      # restore context->R12
-       mov     %r13,224($context)      # restore context->R13
-       mov     %r14,232($context)      # restore context->R14
-       mov     %r15,240($context)      # restore context->R15
-
-.Lin_block_prologue:
-       mov     8(%rax),%rdi
-       mov     16(%rax),%rsi
-       mov     %rax,152($context)      # restore context->Rsp
-       mov     %rsi,168($context)      # restore context->Rsi
-       mov     %rdi,176($context)      # restore context->Rdi
-
-       jmp     .Lcommon_seh_exit
-.size  block_se_handler,.-block_se_handler
-
-.type  key_se_handler,\@abi-omnipotent
-.align 16
-key_se_handler:
-       push    %rsi
-       push    %rdi
-       push    %rbx
-       push    %rbp
-       push    %r12
-       push    %r13
-       push    %r14
-       push    %r15
-       pushfq
-       sub     \$64,%rsp
-
-       mov     120($context),%rax      # pull context->Rax
-       mov     248($context),%rbx      # pull context->Rip
-
-       mov     8($disp),%rsi           # disp->ImageBase
-       mov     56($disp),%r11          # disp->HandlerData
-
-       mov     0(%r11),%r10d           # HandlerData[0]
-       lea     (%rsi,%r10),%r10        # prologue label
-       cmp     %r10,%rbx               # context->Rip<prologue label
-       jb      .Lin_key_prologue
-
-       mov     152($context),%rax      # pull context->Rsp
-
-       mov     4(%r11),%r10d           # HandlerData[1]
-       lea     (%rsi,%r10),%r10        # epilogue label
-       cmp     %r10,%rbx               # context->Rip>=epilogue label
-       jae     .Lin_key_prologue
-
-       lea     56(%rax),%rax
-
-       mov     -8(%rax),%rbx
-       mov     -16(%rax),%rbp
-       mov     -24(%rax),%r12
-       mov     -32(%rax),%r13
-       mov     -40(%rax),%r14
-       mov     -48(%rax),%r15
-       mov     %rbx,144($context)      # restore context->Rbx
-       mov     %rbp,160($context)      # restore context->Rbp
-       mov     %r12,216($context)      # restore context->R12
-       mov     %r13,224($context)      # restore context->R13
-       mov     %r14,232($context)      # restore context->R14
-       mov     %r15,240($context)      # restore context->R15
-
-.Lin_key_prologue:
-       mov     8(%rax),%rdi
-       mov     16(%rax),%rsi
-       mov     %rax,152($context)      # restore context->Rsp
-       mov     %rsi,168($context)      # restore context->Rsi
-       mov     %rdi,176($context)      # restore context->Rdi
-
-       jmp     .Lcommon_seh_exit
-.size  key_se_handler,.-key_se_handler
-
-.type  cbc_se_handler,\@abi-omnipotent
-.align 16
-cbc_se_handler:
-       push    %rsi
-       push    %rdi
-       push    %rbx
-       push    %rbp
-       push    %r12
-       push    %r13
-       push    %r14
-       push    %r15
-       pushfq
-       sub     \$64,%rsp
-
-       mov     120($context),%rax      # pull context->Rax
-       mov     248($context),%rbx      # pull context->Rip
-
-       lea     .Lcbc_prologue(%rip),%r10
-       cmp     %r10,%rbx               # context->Rip<.Lcbc_prologue
-       jb      .Lin_cbc_prologue
-
-       lea     .Lcbc_fast_body(%rip),%r10
-       cmp     %r10,%rbx               # context->Rip<.Lcbc_fast_body
-       jb      .Lin_cbc_frame_setup
-
-       lea     .Lcbc_slow_prologue(%rip),%r10
-       cmp     %r10,%rbx               # context->Rip<.Lcbc_slow_prologue
-       jb      .Lin_cbc_body
-
-       lea     .Lcbc_slow_body(%rip),%r10
-       cmp     %r10,%rbx               # context->Rip<.Lcbc_slow_body
-       jb      .Lin_cbc_frame_setup
-
-.Lin_cbc_body:
-       mov     152($context),%rax      # pull context->Rsp
-
-       lea     .Lcbc_epilogue(%rip),%r10
-       cmp     %r10,%rbx               # context->Rip>=.Lcbc_epilogue
-       jae     .Lin_cbc_prologue
-
-       lea     8(%rax),%rax
-
-       lea     .Lcbc_popfq(%rip),%r10
-       cmp     %r10,%rbx               # context->Rip>=.Lcbc_popfq
-       jae     .Lin_cbc_prologue
-
-       mov     `16-8`(%rax),%rax       # biased $_rsp
-       lea     56(%rax),%rax
-
-.Lin_cbc_frame_setup:
-       mov     -16(%rax),%rbx
-       mov     -24(%rax),%rbp
-       mov     -32(%rax),%r12
-       mov     -40(%rax),%r13
-       mov     -48(%rax),%r14
-       mov     -56(%rax),%r15
-       mov     %rbx,144($context)      # restore context->Rbx
-       mov     %rbp,160($context)      # restore context->Rbp
-       mov     %r12,216($context)      # restore context->R12
-       mov     %r13,224($context)      # restore context->R13
-       mov     %r14,232($context)      # restore context->R14
-       mov     %r15,240($context)      # restore context->R15
-
-.Lin_cbc_prologue:
-       mov     8(%rax),%rdi
-       mov     16(%rax),%rsi
-       mov     %rax,152($context)      # restore context->Rsp
-       mov     %rsi,168($context)      # restore context->Rsi
-       mov     %rdi,176($context)      # restore context->Rdi
-
-.Lcommon_seh_exit:
-
-       mov     40($disp),%rdi          # disp->ContextRecord
-       mov     $context,%rsi           # context
-       mov     \$`1232/8`,%ecx         # sizeof(CONTEXT)
-       .long   0xa548f3fc              # cld; rep movsq
-
-       mov     $disp,%rsi
-       xor     %rcx,%rcx               # arg1, UNW_FLAG_NHANDLER
-       mov     8(%rsi),%rdx            # arg2, disp->ImageBase
-       mov     0(%rsi),%r8             # arg3, disp->ControlPc
-       mov     16(%rsi),%r9            # arg4, disp->FunctionEntry
-       mov     40(%rsi),%r10           # disp->ContextRecord
-       lea     56(%rsi),%r11           # &disp->HandlerData
-       lea     24(%rsi),%r12           # &disp->EstablisherFrame
-       mov     %r10,32(%rsp)           # arg5
-       mov     %r11,40(%rsp)           # arg6
-       mov     %r12,48(%rsp)           # arg7
-       mov     %rcx,56(%rsp)           # arg8, (NULL)
-       call    *__imp_RtlVirtualUnwind(%rip)
-
-       mov     \$1,%eax                # ExceptionContinueSearch
-       add     \$64,%rsp
-       popfq
-       pop     %r15
-       pop     %r14
-       pop     %r13
-       pop     %r12
-       pop     %rbp
-       pop     %rbx
-       pop     %rdi
-       pop     %rsi
-       ret
-.size  cbc_se_handler,.-cbc_se_handler
-
-.section       .pdata
-.align 4
-       .rva    .LSEH_begin_AES_encrypt
-       .rva    .LSEH_end_AES_encrypt
-       .rva    .LSEH_info_AES_encrypt
-
-       .rva    .LSEH_begin_AES_decrypt
-       .rva    .LSEH_end_AES_decrypt
-       .rva    .LSEH_info_AES_decrypt
-
-       .rva    .LSEH_begin_AES_set_encrypt_key
-       .rva    .LSEH_end_AES_set_encrypt_key
-       .rva    .LSEH_info_AES_set_encrypt_key
-
-       .rva    .LSEH_begin_AES_set_decrypt_key
-       .rva    .LSEH_end_AES_set_decrypt_key
-       .rva    .LSEH_info_AES_set_decrypt_key
-
-       .rva    .LSEH_begin_AES_cbc_encrypt
-       .rva    .LSEH_end_AES_cbc_encrypt
-       .rva    .LSEH_info_AES_cbc_encrypt
-
-.section       .xdata
-.align 8
-.LSEH_info_AES_encrypt:
-       .byte   9,0,0,0
-       .rva    block_se_handler
-       .rva    .Lenc_prologue,.Lenc_epilogue   # HandlerData[]
-.LSEH_info_AES_decrypt:
-       .byte   9,0,0,0
-       .rva    block_se_handler
-       .rva    .Ldec_prologue,.Ldec_epilogue   # HandlerData[]
-.LSEH_info_AES_set_encrypt_key:
-       .byte   9,0,0,0
-       .rva    key_se_handler
-       .rva    .Lenc_key_prologue,.Lenc_key_epilogue   # HandlerData[]
-.LSEH_info_AES_set_decrypt_key:
-       .byte   9,0,0,0
-       .rva    key_se_handler
-       .rva    .Ldec_key_prologue,.Ldec_key_epilogue   # HandlerData[]
-.LSEH_info_AES_cbc_encrypt:
-       .byte   9,0,0,0
-       .rva    cbc_se_handler
-___
-}
-
-$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-
-print $code;
-
-close STDOUT;
diff --git a/crypto/aes/asm/bsaes-x86_64.pl b/crypto/aes/asm/bsaes-x86_64.pl
deleted file mode 100644 (file)
index e623427..0000000
+++ /dev/null
@@ -1,3239 +0,0 @@
-#! /usr/bin/env perl
-# Copyright 2011-2019 The OpenSSL Project Authors. All Rights Reserved.
-#
-# Licensed under the OpenSSL license (the "License").  You may not use
-# this file except in compliance with the License.  You can obtain a copy
-# in the file LICENSE in the source distribution or at
-# https://www.openssl.org/source/license.html
-
-
-###################################################################
-### AES-128 [originally in CTR mode]                           ###
-### bitsliced implementation for Intel Core 2 processors       ###
-### requires support of SSE extensions up to SSSE3             ###
-### Author: Emilia Käsper and Peter Schwabe                   ###
-### Date: 2009-03-19                                           ###
-### Public domain                                              ###
-###                                                            ###
-### See http://homes.esat.kuleuven.be/~ekasper/#software for   ###
-### further information.                                       ###
-###################################################################
-#
-# September 2011.
-#
-# Started as transliteration to "perlasm" the original code has
-# undergone following changes:
-#
-# - code was made position-independent;
-# - rounds were folded into a loop resulting in >5x size reduction
-#   from 12.5KB to 2.2KB;
-# - above was possibile thanks to mixcolumns() modification that
-#   allowed to feed its output back to aesenc[last], this was
-#   achieved at cost of two additional inter-registers moves;
-# - some instruction reordering and interleaving;
-# - this module doesn't implement key setup subroutine, instead it
-#   relies on conversion of "conventional" key schedule as returned
-#   by AES_set_encrypt_key (see discussion below);
-# - first and last round keys are treated differently, which allowed
-#   to skip one shiftrows(), reduce bit-sliced key schedule and
-#   speed-up conversion by 22%;
-# - support for 192- and 256-bit keys was added;
-#
-# Resulting performance in CPU cycles spent to encrypt one byte out
-# of 4096-byte buffer with 128-bit key is:
-#
-#              Emilia's        this(*)         difference
-#
-# Core 2       9.30            8.69            +7%
-# Nehalem(**)  7.63            6.88            +11%
-# Atom         17.1            16.4            +4%
-# Silvermont   -               12.9
-# Goldmont     -               8.85
-#
-# (*)  Comparison is not completely fair, because "this" is ECB,
-#      i.e. no extra processing such as counter values calculation
-#      and xor-ing input as in Emilia's CTR implementation is
-#      performed. However, the CTR calculations stand for not more
-#      than 1% of total time, so comparison is *rather* fair.
-#
-# (**) Results were collected on Westmere, which is considered to
-#      be equivalent to Nehalem for this code.
-#
-# As for key schedule conversion subroutine. Interface to OpenSSL
-# relies on per-invocation on-the-fly conversion. This naturally
-# has impact on performance, especially for short inputs. Conversion
-# time in CPU cycles and its ratio to CPU cycles spent in 8x block
-# function is:
-#
-#              conversion      conversion/8x block
-# Core 2       240             0.22
-# Nehalem      180             0.20
-# Atom         430             0.20
-#
-# The ratio values mean that 128-byte blocks will be processed
-# 16-18% slower, 256-byte blocks - 9-10%, 384-byte blocks - 6-7%,
-# etc. Then keep in mind that input sizes not divisible by 128 are
-# *effectively* slower, especially shortest ones, e.g. consecutive
-# 144-byte blocks are processed 44% slower than one would expect,
-# 272 - 29%, 400 - 22%, etc. Yet, despite all these "shortcomings"
-# it's still faster than ["hyper-threading-safe" code path in]
-# aes-x86_64.pl on all lengths above 64 bytes...
-#
-# October 2011.
-#
-# Add decryption procedure. Performance in CPU cycles spent to decrypt
-# one byte out of 4096-byte buffer with 128-bit key is:
-#
-# Core 2       9.98
-# Nehalem      7.80
-# Atom         17.9
-# Silvermont   14.0
-# Goldmont     10.2
-#
-# November 2011.
-#
-# Add bsaes_xts_[en|de]crypt. Less-than-80-bytes-block performance is
-# suboptimal, but XTS is meant to be used with larger blocks...
-#
-#                                              <appro@openssl.org>
-
-$flavour = shift;
-$output  = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-
-$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\"";
-*STDOUT=*OUT;
-
-my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx");
-my @XMM=map("%xmm$_",(15,0..14));      # best on Atom, +10% over (0..15)
-my $ecb=0;     # suppress unreferenced ECB subroutines, spare some space...
-
-{
-my ($key,$rounds,$const)=("%rax","%r10d","%r11");
-
-sub Sbox {
-# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
-my @b=@_[0..7];
-my @t=@_[8..11];
-my @s=@_[12..15];
-       &InBasisChange  (@b);
-       &Inv_GF256      (@b[6,5,0,3,7,1,4,2],@t,@s);
-       &OutBasisChange (@b[7,1,4,2,6,5,0,3]);
-}
-
-sub InBasisChange {
-# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb
-my @b=@_[0..7];
-$code.=<<___;
-       pxor    @b[6], @b[5]
-       pxor    @b[1], @b[2]
-       pxor    @b[0], @b[3]
-       pxor    @b[2], @b[6]
-       pxor    @b[0], @b[5]
-
-       pxor    @b[3], @b[6]
-       pxor    @b[7], @b[3]
-       pxor    @b[5], @b[7]
-       pxor    @b[4], @b[3]
-       pxor    @b[5], @b[4]
-       pxor    @b[1], @b[3]
-
-       pxor    @b[7], @b[2]
-       pxor    @b[5], @b[1]
-___
-}
-
-sub OutBasisChange {
-# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
-my @b=@_[0..7];
-$code.=<<___;
-       pxor    @b[6], @b[0]
-       pxor    @b[4], @b[1]
-       pxor    @b[0], @b[2]
-       pxor    @b[6], @b[4]
-       pxor    @b[1], @b[6]
-
-       pxor    @b[5], @b[1]
-       pxor    @b[3], @b[5]
-       pxor    @b[7], @b[3]
-       pxor    @b[5], @b[7]
-       pxor    @b[5], @b[2]
-
-       pxor    @b[7], @b[4]
-___
-}
-
-sub InvSbox {
-# input in lsb         > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-# output in lsb        > [b0, b1, b6, b4, b2, b7, b3, b5] < msb
-my @b=@_[0..7];
-my @t=@_[8..11];
-my @s=@_[12..15];
-       &InvInBasisChange       (@b);
-       &Inv_GF256              (@b[5,1,2,6,3,7,0,4],@t,@s);
-       &InvOutBasisChange      (@b[3,7,0,4,5,1,2,6]);
-}
-
-sub InvInBasisChange {         # OutBasisChange in reverse
-my @b=@_[5,1,2,6,3,7,0,4];
-$code.=<<___
-       pxor    @b[7], @b[4]
-
-       pxor    @b[5], @b[7]
-       pxor    @b[5], @b[2]
-       pxor    @b[7], @b[3]
-       pxor    @b[3], @b[5]
-       pxor    @b[5], @b[1]
-
-       pxor    @b[1], @b[6]
-       pxor    @b[0], @b[2]
-       pxor    @b[6], @b[4]
-       pxor    @b[6], @b[0]
-       pxor    @b[4], @b[1]
-___
-}
-
-sub InvOutBasisChange {                # InBasisChange in reverse
-my @b=@_[2,5,7,3,6,1,0,4];
-$code.=<<___;
-       pxor    @b[5], @b[1]
-       pxor    @b[7], @b[2]
-
-       pxor    @b[1], @b[3]
-       pxor    @b[5], @b[4]
-       pxor    @b[5], @b[7]
-       pxor    @b[4], @b[3]
-        pxor   @b[0], @b[5]
-       pxor    @b[7], @b[3]
-        pxor   @b[2], @b[6]
-        pxor   @b[1], @b[2]
-       pxor    @b[3], @b[6]
-
-       pxor    @b[0], @b[3]
-       pxor    @b[6], @b[5]
-___
-}
-
-sub Mul_GF4 {
-#;*************************************************************
-#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
-#;*************************************************************
-my ($x0,$x1,$y0,$y1,$t0)=@_;
-$code.=<<___;
-       movdqa  $y0, $t0
-       pxor    $y1, $t0
-       pand    $x0, $t0
-       pxor    $x1, $x0
-       pand    $y0, $x1
-       pand    $y1, $x0
-       pxor    $x1, $x0
-       pxor    $t0, $x1
-___
-}
-
-sub Mul_GF4_N {                                # not used, see next subroutine
-# multiply and scale by N
-my ($x0,$x1,$y0,$y1,$t0)=@_;
-$code.=<<___;
-       movdqa  $y0, $t0
-       pxor    $y1, $t0
-       pand    $x0, $t0
-       pxor    $x1, $x0
-       pand    $y0, $x1
-       pand    $y1, $x0
-       pxor    $x0, $x1
-       pxor    $t0, $x0
-___
-}
-
-sub Mul_GF4_N_GF4 {
-# interleaved Mul_GF4_N and Mul_GF4
-my ($x0,$x1,$y0,$y1,$t0,
-    $x2,$x3,$y2,$y3,$t1)=@_;
-$code.=<<___;
-       movdqa  $y0, $t0
-        movdqa $y2, $t1
-       pxor    $y1, $t0
-        pxor   $y3, $t1
-       pand    $x0, $t0
-        pand   $x2, $t1
-       pxor    $x1, $x0
-        pxor   $x3, $x2
-       pand    $y0, $x1
-        pand   $y2, $x3
-       pand    $y1, $x0
-        pand   $y3, $x2
-       pxor    $x0, $x1
-        pxor   $x3, $x2
-       pxor    $t0, $x0
-        pxor   $t1, $x3
-___
-}
-sub Mul_GF16_2 {
-my @x=@_[0..7];
-my @y=@_[8..11];
-my @t=@_[12..15];
-$code.=<<___;
-       movdqa  @x[0], @t[0]
-       movdqa  @x[1], @t[1]
-___
-       &Mul_GF4        (@x[0], @x[1], @y[0], @y[1], @t[2]);
-$code.=<<___;
-       pxor    @x[2], @t[0]
-       pxor    @x[3], @t[1]
-       pxor    @y[2], @y[0]
-       pxor    @y[3], @y[1]
-___
-       Mul_GF4_N_GF4   (@t[0], @t[1], @y[0], @y[1], @t[3],
-                        @x[2], @x[3], @y[2], @y[3], @t[2]);
-$code.=<<___;
-       pxor    @t[0], @x[0]
-       pxor    @t[0], @x[2]
-       pxor    @t[1], @x[1]
-       pxor    @t[1], @x[3]
-
-       movdqa  @x[4], @t[0]
-       movdqa  @x[5], @t[1]
-       pxor    @x[6], @t[0]
-       pxor    @x[7], @t[1]
-___
-       &Mul_GF4_N_GF4  (@t[0], @t[1], @y[0], @y[1], @t[3],
-                        @x[6], @x[7], @y[2], @y[3], @t[2]);
-$code.=<<___;
-       pxor    @y[2], @y[0]
-       pxor    @y[3], @y[1]
-___
-       &Mul_GF4        (@x[4], @x[5], @y[0], @y[1], @t[3]);
-$code.=<<___;
-       pxor    @t[0], @x[4]
-       pxor    @t[0], @x[6]
-       pxor    @t[1], @x[5]
-       pxor    @t[1], @x[7]
-___
-}
-sub Inv_GF256 {
-#;********************************************************************
-#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144)       *
-#;********************************************************************
-my @x=@_[0..7];
-my @t=@_[8..11];
-my @s=@_[12..15];
-# direct optimizations from hardware
-$code.=<<___;
-       movdqa  @x[4], @t[3]
-       movdqa  @x[5], @t[2]
-       movdqa  @x[1], @t[1]
-       movdqa  @x[7], @s[1]
-       movdqa  @x[0], @s[0]
-
-       pxor    @x[6], @t[3]
-       pxor    @x[7], @t[2]
-       pxor    @x[3], @t[1]
-        movdqa @t[3], @s[2]
-       pxor    @x[6], @s[1]
-        movdqa @t[2], @t[0]
-       pxor    @x[2], @s[0]
-        movdqa @t[3], @s[3]
-
-       por     @t[1], @t[2]
-       por     @s[0], @t[3]
-       pxor    @t[0], @s[3]
-       pand    @s[0], @s[2]
-       pxor    @t[1], @s[0]
-       pand    @t[1], @t[0]
-       pand    @s[0], @s[3]
-       movdqa  @x[3], @s[0]
-       pxor    @x[2], @s[0]
-       pand    @s[0], @s[1]
-       pxor    @s[1], @t[3]
-       pxor    @s[1], @t[2]
-       movdqa  @x[4], @s[1]
-       movdqa  @x[1], @s[0]
-       pxor    @x[5], @s[1]
-       pxor    @x[0], @s[0]
-       movdqa  @s[1], @t[1]
-       pand    @s[0], @s[1]
-       por     @s[0], @t[1]
-       pxor    @s[1], @t[0]
-       pxor    @s[3], @t[3]
-       pxor    @s[2], @t[2]
-       pxor    @s[3], @t[1]
-       movdqa  @x[7], @s[0]
-       pxor    @s[2], @t[0]
-       movdqa  @x[6], @s[1]
-       pxor    @s[2], @t[1]
-       movdqa  @x[5], @s[2]
-       pand    @x[3], @s[0]
-       movdqa  @x[4], @s[3]
-       pand    @x[2], @s[1]
-       pand    @x[1], @s[2]
-       por     @x[0], @s[3]
-       pxor    @s[0], @t[3]
-       pxor    @s[1], @t[2]
-       pxor    @s[2], @t[1]
-       pxor    @s[3], @t[0]
-
-       #Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
-
-       # new smaller inversion
-
-       movdqa  @t[3], @s[0]
-       pand    @t[1], @t[3]
-       pxor    @t[2], @s[0]
-
-       movdqa  @t[0], @s[2]
-       movdqa  @s[0], @s[3]
-       pxor    @t[3], @s[2]
-       pand    @s[2], @s[3]
-
-       movdqa  @t[1], @s[1]
-       pxor    @t[2], @s[3]
-       pxor    @t[0], @s[1]
-
-       pxor    @t[2], @t[3]
-
-       pand    @t[3], @s[1]
-
-       movdqa  @s[2], @t[2]
-       pxor    @t[0], @s[1]
-
-       pxor    @s[1], @t[2]
-       pxor    @s[1], @t[1]
-
-       pand    @t[0], @t[2]
-
-       pxor    @t[2], @s[2]
-       pxor    @t[2], @t[1]
-
-       pand    @s[3], @s[2]
-
-       pxor    @s[0], @s[2]
-___
-# output in s3, s2, s1, t1
-
-# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
-
-# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
-       &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
-
-### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
-}
-
-# AES linear components
-
-sub ShiftRows {
-my @x=@_[0..7];
-my $mask=pop;
-$code.=<<___;
-       pxor    0x00($key),@x[0]
-       pxor    0x10($key),@x[1]
-       pxor    0x20($key),@x[2]
-       pxor    0x30($key),@x[3]
-       pshufb  $mask,@x[0]
-       pshufb  $mask,@x[1]
-       pxor    0x40($key),@x[4]
-       pxor    0x50($key),@x[5]
-       pshufb  $mask,@x[2]
-       pshufb  $mask,@x[3]
-       pxor    0x60($key),@x[6]
-       pxor    0x70($key),@x[7]
-       pshufb  $mask,@x[4]
-       pshufb  $mask,@x[5]
-       pshufb  $mask,@x[6]
-       pshufb  $mask,@x[7]
-       lea     0x80($key),$key
-___
-}
-
-sub MixColumns {
-# modified to emit output in order suitable for feeding back to aesenc[last]
-my @x=@_[0..7];
-my @t=@_[8..15];
-my $inv=@_[16];        # optional
-$code.=<<___;
-       pshufd  \$0x93, @x[0], @t[0]    # x0 <<< 32
-       pshufd  \$0x93, @x[1], @t[1]
-        pxor   @t[0], @x[0]            # x0 ^ (x0 <<< 32)
-       pshufd  \$0x93, @x[2], @t[2]
-        pxor   @t[1], @x[1]
-       pshufd  \$0x93, @x[3], @t[3]
-        pxor   @t[2], @x[2]
-       pshufd  \$0x93, @x[4], @t[4]
-        pxor   @t[3], @x[3]
-       pshufd  \$0x93, @x[5], @t[5]
-        pxor   @t[4], @x[4]
-       pshufd  \$0x93, @x[6], @t[6]
-        pxor   @t[5], @x[5]
-       pshufd  \$0x93, @x[7], @t[7]
-        pxor   @t[6], @x[6]
-        pxor   @t[7], @x[7]
-
-       pxor    @x[0], @t[1]
-       pxor    @x[7], @t[0]
-       pxor    @x[7], @t[1]
-        pshufd \$0x4E, @x[0], @x[0]    # (x0 ^ (x0 <<< 32)) <<< 64)
-       pxor    @x[1], @t[2]
-        pshufd \$0x4E, @x[1], @x[1]
-       pxor    @x[4], @t[5]
-        pxor   @t[0], @x[0]
-       pxor    @x[5], @t[6]
-        pxor   @t[1], @x[1]
-       pxor    @x[3], @t[4]
-        pshufd \$0x4E, @x[4], @t[0]
-       pxor    @x[6], @t[7]
-        pshufd \$0x4E, @x[5], @t[1]
-       pxor    @x[2], @t[3]
-        pshufd \$0x4E, @x[3], @x[4]
-       pxor    @x[7], @t[3]
-        pshufd \$0x4E, @x[7], @x[5]
-       pxor    @x[7], @t[4]
-        pshufd \$0x4E, @x[6], @x[3]
-       pxor    @t[4], @t[0]
-        pshufd \$0x4E, @x[2], @x[6]
-       pxor    @t[5], @t[1]
-___
-$code.=<<___ if (!$inv);
-       pxor    @t[3], @x[4]
-       pxor    @t[7], @x[5]
-       pxor    @t[6], @x[3]
-        movdqa @t[0], @x[2]
-       pxor    @t[2], @x[6]
-        movdqa @t[1], @x[7]
-___
-$code.=<<___ if ($inv);
-       pxor    @x[4], @t[3]
-       pxor    @t[7], @x[5]
-       pxor    @x[3], @t[6]
-        movdqa @t[0], @x[3]
-       pxor    @t[2], @x[6]
-        movdqa @t[6], @x[2]
-        movdqa @t[1], @x[7]
-        movdqa @x[6], @x[4]
-        movdqa @t[3], @x[6]
-___
-}
-
-sub InvMixColumns_orig {
-my @x=@_[0..7];
-my @t=@_[8..15];
-
-$code.=<<___;
-       # multiplication by 0x0e
-       pshufd  \$0x93, @x[7], @t[7]
-       movdqa  @x[2], @t[2]
-       pxor    @x[5], @x[7]            # 7 5
-       pxor    @x[5], @x[2]            # 2 5
-       pshufd  \$0x93, @x[0], @t[0]
-       movdqa  @x[5], @t[5]
-       pxor    @x[0], @x[5]            # 5 0           [1]
-       pxor    @x[1], @x[0]            # 0 1
-       pshufd  \$0x93, @x[1], @t[1]
-       pxor    @x[2], @x[1]            # 1 25
-       pxor    @x[6], @x[0]            # 01 6          [2]
-       pxor    @x[3], @x[1]            # 125 3         [4]
-       pshufd  \$0x93, @x[3], @t[3]
-       pxor    @x[0], @x[2]            # 25 016        [3]
-       pxor    @x[7], @x[3]            # 3 75
-       pxor    @x[6], @x[7]            # 75 6          [0]
-       pshufd  \$0x93, @x[6], @t[6]
-       movdqa  @x[4], @t[4]
-       pxor    @x[4], @x[6]            # 6 4
-       pxor    @x[3], @x[4]            # 4 375         [6]
-       pxor    @x[7], @x[3]            # 375 756=36
-       pxor    @t[5], @x[6]            # 64 5          [7]
-       pxor    @t[2], @x[3]            # 36 2
-       pxor    @t[4], @x[3]            # 362 4         [5]
-       pshufd  \$0x93, @t[5], @t[5]
-___
-                                       my @y = @x[7,5,0,2,1,3,4,6];
-$code.=<<___;
-       # multiplication by 0x0b
-       pxor    @y[0], @y[1]
-       pxor    @t[0], @y[0]
-       pxor    @t[1], @y[1]
-       pshufd  \$0x93, @t[2], @t[2]
-       pxor    @t[5], @y[0]
-       pxor    @t[6], @y[1]
-       pxor    @t[7], @y[0]
-       pshufd  \$0x93, @t[4], @t[4]
-       pxor    @t[6], @t[7]            # clobber t[7]
-       pxor    @y[0], @y[1]
-
-       pxor    @t[0], @y[3]
-       pshufd  \$0x93, @t[0], @t[0]
-       pxor    @t[1], @y[2]
-       pxor    @t[1], @y[4]
-       pxor    @t[2], @y[2]
-       pshufd  \$0x93, @t[1], @t[1]
-       pxor    @t[2], @y[3]
-       pxor    @t[2], @y[5]
-       pxor    @t[7], @y[2]
-       pshufd  \$0x93, @t[2], @t[2]
-       pxor    @t[3], @y[3]
-       pxor    @t[3], @y[6]
-       pxor    @t[3], @y[4]
-       pshufd  \$0x93, @t[3], @t[3]
-       pxor    @t[4], @y[7]
-       pxor    @t[4], @y[5]
-       pxor    @t[7], @y[7]
-       pxor    @t[5], @y[3]
-       pxor    @t[4], @y[4]
-       pxor    @t[5], @t[7]            # clobber t[7] even more
-
-       pxor    @t[7], @y[5]
-       pshufd  \$0x93, @t[4], @t[4]
-       pxor    @t[7], @y[6]
-       pxor    @t[7], @y[4]
-
-       pxor    @t[5], @t[7]
-       pshufd  \$0x93, @t[5], @t[5]
-       pxor    @t[6], @t[7]            # restore t[7]
-
-       # multiplication by 0x0d
-       pxor    @y[7], @y[4]
-       pxor    @t[4], @y[7]
-       pshufd  \$0x93, @t[6], @t[6]
-       pxor    @t[0], @y[2]
-       pxor    @t[5], @y[7]
-       pxor    @t[2], @y[2]
-       pshufd  \$0x93, @t[7], @t[7]
-
-       pxor    @y[1], @y[3]
-       pxor    @t[1], @y[1]
-       pxor    @t[0], @y[0]
-       pxor    @t[0], @y[3]
-       pxor    @t[5], @y[1]
-       pxor    @t[5], @y[0]
-       pxor    @t[7], @y[1]
-       pshufd  \$0x93, @t[0], @t[0]
-       pxor    @t[6], @y[0]
-       pxor    @y[1], @y[3]
-       pxor    @t[1], @y[4]
-       pshufd  \$0x93, @t[1], @t[1]
-
-       pxor    @t[7], @y[7]
-       pxor    @t[2], @y[4]
-       pxor    @t[2], @y[5]
-       pshufd  \$0x93, @t[2], @t[2]
-       pxor    @t[6], @y[2]
-       pxor    @t[3], @t[6]            # clobber t[6]
-       pxor    @y[7], @y[4]
-       pxor    @t[6], @y[3]
-
-       pxor    @t[6], @y[6]
-       pxor    @t[5], @y[5]
-       pxor    @t[4], @y[6]
-       pshufd  \$0x93, @t[4], @t[4]
-       pxor    @t[6], @y[5]
-       pxor    @t[7], @y[6]
-       pxor    @t[3], @t[6]            # restore t[6]
-
-       pshufd  \$0x93, @t[5], @t[5]
-       pshufd  \$0x93, @t[6], @t[6]
-       pshufd  \$0x93, @t[7], @t[7]
-       pshufd  \$0x93, @t[3], @t[3]
-
-       # multiplication by 0x09
-       pxor    @y[1], @y[4]
-       pxor    @y[1], @t[1]            # t[1]=y[1]
-       pxor    @t[5], @t[0]            # clobber t[0]
-       pxor    @t[5], @t[1]
-       pxor    @t[0], @y[3]
-       pxor    @y[0], @t[0]            # t[0]=y[0]
-       pxor    @t[6], @t[1]
-       pxor    @t[7], @t[6]            # clobber t[6]
-       pxor    @t[1], @y[4]
-       pxor    @t[4], @y[7]
-       pxor    @y[4], @t[4]            # t[4]=y[4]
-       pxor    @t[3], @y[6]
-       pxor    @y[3], @t[3]            # t[3]=y[3]
-       pxor    @t[2], @y[5]
-       pxor    @y[2], @t[2]            # t[2]=y[2]
-       pxor    @t[7], @t[3]
-       pxor    @y[5], @t[5]            # t[5]=y[5]
-       pxor    @t[6], @t[2]
-       pxor    @t[6], @t[5]
-       pxor    @y[6], @t[6]            # t[6]=y[6]
-       pxor    @y[7], @t[7]            # t[7]=y[7]
-
-       movdqa  @t[0],@XMM[0]
-       movdqa  @t[1],@XMM[1]
-       movdqa  @t[2],@XMM[2]
-       movdqa  @t[3],@XMM[3]
-       movdqa  @t[4],@XMM[4]
-       movdqa  @t[5],@XMM[5]
-       movdqa  @t[6],@XMM[6]
-       movdqa  @t[7],@XMM[7]
-___
-}
-
-sub InvMixColumns {
-my @x=@_[0..7];
-my @t=@_[8..15];
-
-# Thanks to Jussi Kivilinna for providing pointer to
-#
-# | 0e 0b 0d 09 |   | 02 03 01 01 |   | 05 00 04 00 |
-# | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 |
-# | 0d 09 0e 0b |   | 01 01 02 03 |   | 04 00 05 00 |
-# | 0b 0d 09 0e |   | 03 01 01 02 |   | 00 04 00 05 |
-
-$code.=<<___;
-       # multiplication by 0x05-0x00-0x04-0x00
-       pshufd  \$0x4E, @x[0], @t[0]
-       pshufd  \$0x4E, @x[6], @t[6]
-       pxor    @x[0], @t[0]
-       pshufd  \$0x4E, @x[7], @t[7]
-       pxor    @x[6], @t[6]
-       pshufd  \$0x4E, @x[1], @t[1]
-       pxor    @x[7], @t[7]
-       pshufd  \$0x4E, @x[2], @t[2]
-       pxor    @x[1], @t[1]
-       pshufd  \$0x4E, @x[3], @t[3]
-       pxor    @x[2], @t[2]
-        pxor   @t[6], @x[0]
-        pxor   @t[6], @x[1]
-       pshufd  \$0x4E, @x[4], @t[4]
-       pxor    @x[3], @t[3]
-        pxor   @t[0], @x[2]
-        pxor   @t[1], @x[3]
-       pshufd  \$0x4E, @x[5], @t[5]
-       pxor    @x[4], @t[4]
-        pxor   @t[7], @x[1]
-        pxor   @t[2], @x[4]
-       pxor    @x[5], @t[5]
-
-        pxor   @t[7], @x[2]
-        pxor   @t[6], @x[3]
-        pxor   @t[6], @x[4]
-        pxor   @t[3], @x[5]
-        pxor   @t[4], @x[6]
-        pxor   @t[7], @x[4]
-        pxor   @t[7], @x[5]
-        pxor   @t[5], @x[7]
-___
-       &MixColumns     (@x,@t,1);      # flipped 2<->3 and 4<->6
-}
-
-sub aesenc {                           # not used
-my @b=@_[0..7];
-my @t=@_[8..15];
-$code.=<<___;
-       movdqa  0x30($const),@t[0]      # .LSR
-___
-       &ShiftRows      (@b,@t[0]);
-       &Sbox           (@b,@t);
-       &MixColumns     (@b[0,1,4,6,3,7,2,5],@t);
-}
-
-sub aesenclast {                       # not used
-my @b=@_[0..7];
-my @t=@_[8..15];
-$code.=<<___;
-       movdqa  0x40($const),@t[0]      # .LSRM0
-___
-       &ShiftRows      (@b,@t[0]);
-       &Sbox           (@b,@t);
-$code.=<<___
-       pxor    0x00($key),@b[0]
-       pxor    0x10($key),@b[1]
-       pxor    0x20($key),@b[4]
-       pxor    0x30($key),@b[6]
-       pxor    0x40($key),@b[3]
-       pxor    0x50($key),@b[7]
-       pxor    0x60($key),@b[2]
-       pxor    0x70($key),@b[5]
-___
-}
-
-sub swapmove {
-my ($a,$b,$n,$mask,$t)=@_;
-$code.=<<___;
-       movdqa  $b,$t
-       psrlq   \$$n,$b
-       pxor    $a,$b
-       pand    $mask,$b
-       pxor    $b,$a
-       psllq   \$$n,$b
-       pxor    $t,$b
-___
-}
-sub swapmove2x {
-my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
-$code.=<<___;
-       movdqa  $b0,$t0
-       psrlq   \$$n,$b0
-        movdqa $b1,$t1
-        psrlq  \$$n,$b1
-       pxor    $a0,$b0
-        pxor   $a1,$b1
-       pand    $mask,$b0
-        pand   $mask,$b1
-       pxor    $b0,$a0
-       psllq   \$$n,$b0
-        pxor   $b1,$a1
-        psllq  \$$n,$b1
-       pxor    $t0,$b0
-        pxor   $t1,$b1
-___
-}
-
-sub bitslice {
-my @x=reverse(@_[0..7]);
-my ($t0,$t1,$t2,$t3)=@_[8..11];
-$code.=<<___;
-       movdqa  0x00($const),$t0        # .LBS0
-       movdqa  0x10($const),$t1        # .LBS1
-___
-       &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
-       &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
-$code.=<<___;
-       movdqa  0x20($const),$t0        # .LBS2
-___
-       &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
-       &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
-
-       &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
-       &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
-}
-
-$code.=<<___;
-.text
-
-.extern        asm_AES_encrypt
-.extern        asm_AES_decrypt
-
-.type  _bsaes_encrypt8,\@abi-omnipotent
-.align 64
-_bsaes_encrypt8:
-.cfi_startproc
-       lea     .LBS0(%rip), $const     # constants table
-
-       movdqa  ($key), @XMM[9]         # round 0 key
-       lea     0x10($key), $key
-       movdqa  0x50($const), @XMM[8]   # .LM0SR
-       pxor    @XMM[9], @XMM[0]        # xor with round0 key
-       pxor    @XMM[9], @XMM[1]
-       pxor    @XMM[9], @XMM[2]
-       pxor    @XMM[9], @XMM[3]
-        pshufb @XMM[8], @XMM[0]
-        pshufb @XMM[8], @XMM[1]
-       pxor    @XMM[9], @XMM[4]
-       pxor    @XMM[9], @XMM[5]
-        pshufb @XMM[8], @XMM[2]
-        pshufb @XMM[8], @XMM[3]
-       pxor    @XMM[9], @XMM[6]
-       pxor    @XMM[9], @XMM[7]
-        pshufb @XMM[8], @XMM[4]
-        pshufb @XMM[8], @XMM[5]
-        pshufb @XMM[8], @XMM[6]
-        pshufb @XMM[8], @XMM[7]
-_bsaes_encrypt8_bitslice:
-___
-       &bitslice       (@XMM[0..7, 8..11]);
-$code.=<<___;
-       dec     $rounds
-       jmp     .Lenc_sbox
-.align 16
-.Lenc_loop:
-___
-       &ShiftRows      (@XMM[0..7, 8]);
-$code.=".Lenc_sbox:\n";
-       &Sbox           (@XMM[0..7, 8..15]);
-$code.=<<___;
-       dec     $rounds
-       jl      .Lenc_done
-___
-       &MixColumns     (@XMM[0,1,4,6,3,7,2,5, 8..15]);
-$code.=<<___;
-       movdqa  0x30($const), @XMM[8]   # .LSR
-       jnz     .Lenc_loop
-       movdqa  0x40($const), @XMM[8]   # .LSRM0
-       jmp     .Lenc_loop
-.align 16
-.Lenc_done:
-___
-       # output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
-       &bitslice       (@XMM[0,1,4,6,3,7,2,5, 8..11]);
-$code.=<<___;
-       movdqa  ($key), @XMM[8]         # last round key
-       pxor    @XMM[8], @XMM[4]
-       pxor    @XMM[8], @XMM[6]
-       pxor    @XMM[8], @XMM[3]
-       pxor    @XMM[8], @XMM[7]
-       pxor    @XMM[8], @XMM[2]
-       pxor    @XMM[8], @XMM[5]
-       pxor    @XMM[8], @XMM[0]
-       pxor    @XMM[8], @XMM[1]
-       ret
-.cfi_endproc
-.size  _bsaes_encrypt8,.-_bsaes_encrypt8
-
-.type  _bsaes_decrypt8,\@abi-omnipotent
-.align 64
-_bsaes_decrypt8:
-.cfi_startproc
-       lea     .LBS0(%rip), $const     # constants table
-
-       movdqa  ($key), @XMM[9]         # round 0 key
-       lea     0x10($key), $key
-       movdqa  -0x30($const), @XMM[8]  # .LM0ISR
-       pxor    @XMM[9], @XMM[0]        # xor with round0 key
-       pxor    @XMM[9], @XMM[1]
-       pxor    @XMM[9], @XMM[2]
-       pxor    @XMM[9], @XMM[3]
-        pshufb @XMM[8], @XMM[0]
-        pshufb @XMM[8], @XMM[1]
-       pxor    @XMM[9], @XMM[4]
-       pxor    @XMM[9], @XMM[5]
-        pshufb @XMM[8], @XMM[2]
-        pshufb @XMM[8], @XMM[3]
-       pxor    @XMM[9], @XMM[6]
-       pxor    @XMM[9], @XMM[7]
-        pshufb @XMM[8], @XMM[4]
-        pshufb @XMM[8], @XMM[5]
-        pshufb @XMM[8], @XMM[6]
-        pshufb @XMM[8], @XMM[7]
-___
-       &bitslice       (@XMM[0..7, 8..11]);
-$code.=<<___;
-       dec     $rounds
-       jmp     .Ldec_sbox
-.align 16
-.Ldec_loop:
-___
-       &ShiftRows      (@XMM[0..7, 8]);
-$code.=".Ldec_sbox:\n";
-       &InvSbox        (@XMM[0..7, 8..15]);
-$code.=<<___;
-       dec     $rounds
-       jl      .Ldec_done
-___
-       &InvMixColumns  (@XMM[0,1,6,4,2,7,3,5, 8..15]);
-$code.=<<___;
-       movdqa  -0x10($const), @XMM[8]  # .LISR
-       jnz     .Ldec_loop
-       movdqa  -0x20($const), @XMM[8]  # .LISRM0
-       jmp     .Ldec_loop
-.align 16
-.Ldec_done:
-___
-       &bitslice       (@XMM[0,1,6,4,2,7,3,5, 8..11]);
-$code.=<<___;
-       movdqa  ($key), @XMM[8]         # last round key
-       pxor    @XMM[8], @XMM[6]
-       pxor    @XMM[8], @XMM[4]
-       pxor    @XMM[8], @XMM[2]
-       pxor    @XMM[8], @XMM[7]
-       pxor    @XMM[8], @XMM[3]
-       pxor    @XMM[8], @XMM[5]
-       pxor    @XMM[8], @XMM[0]
-       pxor    @XMM[8], @XMM[1]
-       ret
-.cfi_endproc
-.size  _bsaes_decrypt8,.-_bsaes_decrypt8
-___
-}
-{
-my ($out,$inp,$rounds,$const)=("%rax","%rcx","%r10d","%r11");
-
-sub bitslice_key {
-my @x=reverse(@_[0..7]);
-my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
-
-       &swapmove       (@x[0,1],1,$bs0,$t2,$t3);
-$code.=<<___;
-       #&swapmove(@x[2,3],1,$t0,$t2,$t3);
-       movdqa  @x[0], @x[2]
-       movdqa  @x[1], @x[3]
-___
-       #&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
-
-       &swapmove2x     (@x[0,2,1,3],2,$bs1,$t2,$t3);
-$code.=<<___;
-       #&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
-       movdqa  @x[0], @x[4]
-       movdqa  @x[2], @x[6]
-       movdqa  @x[1], @x[5]
-       movdqa  @x[3], @x[7]
-___
-       &swapmove2x     (@x[0,4,1,5],4,$bs2,$t2,$t3);
-       &swapmove2x     (@x[2,6,3,7],4,$bs2,$t2,$t3);
-}
-
-$code.=<<___;
-.type  _bsaes_key_convert,\@abi-omnipotent
-.align 16
-_bsaes_key_convert:
-.cfi_startproc
-       lea     .Lmasks(%rip), $const
-       movdqu  ($inp), %xmm7           # load round 0 key
-       lea     0x10($inp), $inp
-       movdqa  0x00($const), %xmm0     # 0x01...
-       movdqa  0x10($const), %xmm1     # 0x02...
-       movdqa  0x20($const), %xmm2     # 0x04...
-       movdqa  0x30($const), %xmm3     # 0x08...
-       movdqa  0x40($const), %xmm4     # .LM0
-       pcmpeqd %xmm5, %xmm5            # .LNOT
-
-       movdqu  ($inp), %xmm6           # load round 1 key
-       movdqa  %xmm7, ($out)           # save round 0 key
-       lea     0x10($out), $out
-       dec     $rounds
-       jmp     .Lkey_loop
-.align 16
-.Lkey_loop:
-       pshufb  %xmm4, %xmm6            # .LM0
-
-       movdqa  %xmm0,  %xmm8
-       movdqa  %xmm1,  %xmm9
-
-       pand    %xmm6,  %xmm8
-       pand    %xmm6,  %xmm9
-       movdqa  %xmm2,  %xmm10
-       pcmpeqb %xmm0,  %xmm8
-       psllq   \$4,    %xmm0           # 0x10...
-       movdqa  %xmm3,  %xmm11
-       pcmpeqb %xmm1,  %xmm9
-       psllq   \$4,    %xmm1           # 0x20...
-
-       pand    %xmm6,  %xmm10
-       pand    %xmm6,  %xmm11
-       movdqa  %xmm0,  %xmm12
-       pcmpeqb %xmm2,  %xmm10
-       psllq   \$4,    %xmm2           # 0x40...
-       movdqa  %xmm1,  %xmm13
-       pcmpeqb %xmm3,  %xmm11
-       psllq   \$4,    %xmm3           # 0x80...
-
-       movdqa  %xmm2,  %xmm14
-       movdqa  %xmm3,  %xmm15
-        pxor   %xmm5,  %xmm8           # "pnot"
-        pxor   %xmm5,  %xmm9
-
-       pand    %xmm6,  %xmm12
-       pand    %xmm6,  %xmm13
-        movdqa %xmm8, 0x00($out)       # write bit-sliced round key
-       pcmpeqb %xmm0,  %xmm12
-       psrlq   \$4,    %xmm0           # 0x01...
-        movdqa %xmm9, 0x10($out)
-       pcmpeqb %xmm1,  %xmm13
-       psrlq   \$4,    %xmm1           # 0x02...
-        lea    0x10($inp), $inp
-
-       pand    %xmm6,  %xmm14
-       pand    %xmm6,  %xmm15
-        movdqa %xmm10, 0x20($out)
-       pcmpeqb %xmm2,  %xmm14
-       psrlq   \$4,    %xmm2           # 0x04...
-        movdqa %xmm11, 0x30($out)
-       pcmpeqb %xmm3,  %xmm15
-       psrlq   \$4,    %xmm3           # 0x08...
-        movdqu ($inp), %xmm6           # load next round key
-
-       pxor    %xmm5, %xmm13           # "pnot"
-       pxor    %xmm5, %xmm14
-       movdqa  %xmm12, 0x40($out)
-       movdqa  %xmm13, 0x50($out)
-       movdqa  %xmm14, 0x60($out)
-       movdqa  %xmm15, 0x70($out)
-       lea     0x80($out),$out
-       dec     $rounds
-       jnz     .Lkey_loop
-
-       movdqa  0x50($const), %xmm7     # .L63
-       #movdqa %xmm6, ($out)           # don't save last round key
-       ret
-.cfi_endproc
-.size  _bsaes_key_convert,.-_bsaes_key_convert
-___
-}
-
-if (0 && !$win64) {    # following four functions are unsupported interface
-                       # used for benchmarking...
-$code.=<<___;
-.globl bsaes_enc_key_convert
-.type  bsaes_enc_key_convert,\@function,2
-.align 16
-bsaes_enc_key_convert:
-       mov     240($inp),%r10d         # pass rounds
-       mov     $inp,%rcx               # pass key
-       mov     $out,%rax               # pass key schedule
-       call    _bsaes_key_convert
-       pxor    %xmm6,%xmm7             # fix up last round key
-       movdqa  %xmm7,(%rax)            # save last round key
-       ret
-.size  bsaes_enc_key_convert,.-bsaes_enc_key_convert
-
-.globl bsaes_encrypt_128
-.type  bsaes_encrypt_128,\@function,4
-.align 16
-bsaes_encrypt_128:
-.Lenc128_loop:
-       movdqu  0x00($inp), @XMM[0]     # load input
-       movdqu  0x10($inp), @XMM[1]
-       movdqu  0x20($inp), @XMM[2]
-       movdqu  0x30($inp), @XMM[3]
-       movdqu  0x40($inp), @XMM[4]
-       movdqu  0x50($inp), @XMM[5]
-       movdqu  0x60($inp), @XMM[6]
-       movdqu  0x70($inp), @XMM[7]
-       mov     $key, %rax              # pass the $key
-       lea     0x80($inp), $inp
-       mov     \$10,%r10d
-
-       call    _bsaes_encrypt8
-
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[4], 0x20($out)
-       movdqu  @XMM[6], 0x30($out)
-       movdqu  @XMM[3], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[2], 0x60($out)
-       movdqu  @XMM[5], 0x70($out)
-       lea     0x80($out), $out
-       sub     \$0x80,$len
-       ja      .Lenc128_loop
-       ret
-.size  bsaes_encrypt_128,.-bsaes_encrypt_128
-
-.globl bsaes_dec_key_convert
-.type  bsaes_dec_key_convert,\@function,2
-.align 16
-bsaes_dec_key_convert:
-       mov     240($inp),%r10d         # pass rounds
-       mov     $inp,%rcx               # pass key
-       mov     $out,%rax               # pass key schedule
-       call    _bsaes_key_convert
-       pxor    ($out),%xmm7            # fix up round 0 key
-       movdqa  %xmm6,(%rax)            # save last round key
-       movdqa  %xmm7,($out)
-       ret
-.size  bsaes_dec_key_convert,.-bsaes_dec_key_convert
-
-.globl bsaes_decrypt_128
-.type  bsaes_decrypt_128,\@function,4
-.align 16
-bsaes_decrypt_128:
-.Ldec128_loop:
-       movdqu  0x00($inp), @XMM[0]     # load input
-       movdqu  0x10($inp), @XMM[1]
-       movdqu  0x20($inp), @XMM[2]
-       movdqu  0x30($inp), @XMM[3]
-       movdqu  0x40($inp), @XMM[4]
-       movdqu  0x50($inp), @XMM[5]
-       movdqu  0x60($inp), @XMM[6]
-       movdqu  0x70($inp), @XMM[7]
-       mov     $key, %rax              # pass the $key
-       lea     0x80($inp), $inp
-       mov     \$10,%r10d
-
-       call    _bsaes_decrypt8
-
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[3], 0x60($out)
-       movdqu  @XMM[5], 0x70($out)
-       lea     0x80($out), $out
-       sub     \$0x80,$len
-       ja      .Ldec128_loop
-       ret
-.size  bsaes_decrypt_128,.-bsaes_decrypt_128
-___
-}
-{
-######################################################################
-#
-# OpenSSL interface
-#
-my ($arg1,$arg2,$arg3,$arg4,$arg5,$arg6)=$win64        ? ("%rcx","%rdx","%r8","%r9","%r10","%r11d")
-                                               : ("%rdi","%rsi","%rdx","%rcx","%r8","%r9d");
-my ($inp,$out,$len,$key)=("%r12","%r13","%r14","%r15");
-
-if ($ecb) {
-$code.=<<___;
-.globl bsaes_ecb_encrypt_blocks
-.type  bsaes_ecb_encrypt_blocks,\@abi-omnipotent
-.align 16
-bsaes_ecb_encrypt_blocks:
-.cfi_startproc
-       mov     %rsp, %rax
-.Lecb_enc_prologue:
-       push    %rbp
-.cfi_push      %rbp
-       push    %rbx
-.cfi_push      %rbx
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-       lea     -0x48(%rsp),%rsp
-.cfi_adjust_cfa_offset 0x48
-___
-$code.=<<___ if ($win64);
-       lea     -0xa0(%rsp), %rsp
-       movaps  %xmm6, 0x40(%rsp)
-       movaps  %xmm7, 0x50(%rsp)
-       movaps  %xmm8, 0x60(%rsp)
-       movaps  %xmm9, 0x70(%rsp)
-       movaps  %xmm10, 0x80(%rsp)
-       movaps  %xmm11, 0x90(%rsp)
-       movaps  %xmm12, 0xa0(%rsp)
-       movaps  %xmm13, 0xb0(%rsp)
-       movaps  %xmm14, 0xc0(%rsp)
-       movaps  %xmm15, 0xd0(%rsp)
-.Lecb_enc_body:
-___
-$code.=<<___;
-       mov     %rsp,%rbp               # backup %rsp
-.cfi_def_cfa_register  %rbp
-       mov     240($arg4),%eax         # rounds
-       mov     $arg1,$inp              # backup arguments
-       mov     $arg2,$out
-       mov     $arg3,$len
-       mov     $arg4,$key
-       cmp     \$8,$arg3
-       jb      .Lecb_enc_short
-
-       mov     %eax,%ebx               # backup rounds
-       shl     \$7,%rax                # 128 bytes per inner round key
-       sub     \$`128-32`,%rax         # size of bit-sliced key schedule
-       sub     %rax,%rsp
-       mov     %rsp,%rax               # pass key schedule
-       mov     $key,%rcx               # pass key
-       mov     %ebx,%r10d              # pass rounds
-       call    _bsaes_key_convert
-       pxor    %xmm6,%xmm7             # fix up last round key
-       movdqa  %xmm7,(%rax)            # save last round key
-
-       sub     \$8,$len
-.Lecb_enc_loop:
-       movdqu  0x00($inp), @XMM[0]     # load input
-       movdqu  0x10($inp), @XMM[1]
-       movdqu  0x20($inp), @XMM[2]
-       movdqu  0x30($inp), @XMM[3]
-       movdqu  0x40($inp), @XMM[4]
-       movdqu  0x50($inp), @XMM[5]
-       mov     %rsp, %rax              # pass key schedule
-       movdqu  0x60($inp), @XMM[6]
-       mov     %ebx,%r10d              # pass rounds
-       movdqu  0x70($inp), @XMM[7]
-       lea     0x80($inp), $inp
-
-       call    _bsaes_encrypt8
-
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[4], 0x20($out)
-       movdqu  @XMM[6], 0x30($out)
-       movdqu  @XMM[3], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[2], 0x60($out)
-       movdqu  @XMM[5], 0x70($out)
-       lea     0x80($out), $out
-       sub     \$8,$len
-       jnc     .Lecb_enc_loop
-
-       add     \$8,$len
-       jz      .Lecb_enc_done
-
-       movdqu  0x00($inp), @XMM[0]     # load input
-       mov     %rsp, %rax              # pass key schedule
-       mov     %ebx,%r10d              # pass rounds
-       cmp     \$2,$len
-       jb      .Lecb_enc_one
-       movdqu  0x10($inp), @XMM[1]
-       je      .Lecb_enc_two
-       movdqu  0x20($inp), @XMM[2]
-       cmp     \$4,$len
-       jb      .Lecb_enc_three
-       movdqu  0x30($inp), @XMM[3]
-       je      .Lecb_enc_four
-       movdqu  0x40($inp), @XMM[4]
-       cmp     \$6,$len
-       jb      .Lecb_enc_five
-       movdqu  0x50($inp), @XMM[5]
-       je      .Lecb_enc_six
-       movdqu  0x60($inp), @XMM[6]
-       call    _bsaes_encrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[4], 0x20($out)
-       movdqu  @XMM[6], 0x30($out)
-       movdqu  @XMM[3], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[2], 0x60($out)
-       jmp     .Lecb_enc_done
-.align 16
-.Lecb_enc_six:
-       call    _bsaes_encrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[4], 0x20($out)
-       movdqu  @XMM[6], 0x30($out)
-       movdqu  @XMM[3], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       jmp     .Lecb_enc_done
-.align 16
-.Lecb_enc_five:
-       call    _bsaes_encrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[4], 0x20($out)
-       movdqu  @XMM[6], 0x30($out)
-       movdqu  @XMM[3], 0x40($out)
-       jmp     .Lecb_enc_done
-.align 16
-.Lecb_enc_four:
-       call    _bsaes_encrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[4], 0x20($out)
-       movdqu  @XMM[6], 0x30($out)
-       jmp     .Lecb_enc_done
-.align 16
-.Lecb_enc_three:
-       call    _bsaes_encrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[4], 0x20($out)
-       jmp     .Lecb_enc_done
-.align 16
-.Lecb_enc_two:
-       call    _bsaes_encrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       jmp     .Lecb_enc_done
-.align 16
-.Lecb_enc_one:
-       call    _bsaes_encrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       jmp     .Lecb_enc_done
-.align 16
-.Lecb_enc_short:
-       lea     ($inp), $arg1
-       lea     ($out), $arg2
-       lea     ($key), $arg3
-       call    asm_AES_encrypt
-       lea     16($inp), $inp
-       lea     16($out), $out
-       dec     $len
-       jnz     .Lecb_enc_short
-
-.Lecb_enc_done:
-       lea     (%rsp),%rax
-       pxor    %xmm0, %xmm0
-.Lecb_enc_bzero:                       # wipe key schedule [if any]
-       movdqa  %xmm0, 0x00(%rax)
-       movdqa  %xmm0, 0x10(%rax)
-       lea     0x20(%rax), %rax
-       cmp     %rax, %rbp
-       jb      .Lecb_enc_bzero
-
-       lea     0x78(%rbp),%rax
-.cfi_def_cfa   %rax,8
-___
-$code.=<<___ if ($win64);
-       movaps  0x40(%rbp), %xmm6
-       movaps  0x50(%rbp), %xmm7
-       movaps  0x60(%rbp), %xmm8
-       movaps  0x70(%rbp), %xmm9
-       movaps  0x80(%rbp), %xmm10
-       movaps  0x90(%rbp), %xmm11
-       movaps  0xa0(%rbp), %xmm12
-       movaps  0xb0(%rbp), %xmm13
-       movaps  0xc0(%rbp), %xmm14
-       movaps  0xd0(%rbp), %xmm15
-       lea     0xa0(%rax), %rax
-.Lecb_enc_tail:
-___
-$code.=<<___;
-       mov     -48(%rax), %r15
-.cfi_restore   %r15
-       mov     -40(%rax), %r14
-.cfi_restore   %r14
-       mov     -32(%rax), %r13
-.cfi_restore   %r13
-       mov     -24(%rax), %r12
-.cfi_restore   %r12
-       mov     -16(%rax), %rbx
-.cfi_restore   %rbx
-       mov     -8(%rax), %rbp
-.cfi_restore   %rbp
-       lea     (%rax), %rsp            # restore %rsp
-.cfi_def_cfa_register  %rsp
-.Lecb_enc_epilogue:
-       ret
-.cfi_endproc
-.size  bsaes_ecb_encrypt_blocks,.-bsaes_ecb_encrypt_blocks
-
-.globl bsaes_ecb_decrypt_blocks
-.type  bsaes_ecb_decrypt_blocks,\@abi-omnipotent
-.align 16
-bsaes_ecb_decrypt_blocks:
-.cfi_startproc
-       mov     %rsp, %rax
-.Lecb_dec_prologue:
-       push    %rbp
-.cfi_push      %rbp
-       push    %rbx
-.cfi_push      %rbx
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-       lea     -0x48(%rsp),%rsp
-.cfi_adjust_cfa_offset 0x48
-___
-$code.=<<___ if ($win64);
-       lea     -0xa0(%rsp), %rsp
-       movaps  %xmm6, 0x40(%rsp)
-       movaps  %xmm7, 0x50(%rsp)
-       movaps  %xmm8, 0x60(%rsp)
-       movaps  %xmm9, 0x70(%rsp)
-       movaps  %xmm10, 0x80(%rsp)
-       movaps  %xmm11, 0x90(%rsp)
-       movaps  %xmm12, 0xa0(%rsp)
-       movaps  %xmm13, 0xb0(%rsp)
-       movaps  %xmm14, 0xc0(%rsp)
-       movaps  %xmm15, 0xd0(%rsp)
-.Lecb_dec_body:
-___
-$code.=<<___;
-       mov     %rsp,%rbp               # backup %rsp
-.cfi_def_cfa_register  %rbp
-       mov     240($arg4),%eax         # rounds
-       mov     $arg1,$inp              # backup arguments
-       mov     $arg2,$out
-       mov     $arg3,$len
-       mov     $arg4,$key
-       cmp     \$8,$arg3
-       jb      .Lecb_dec_short
-
-       mov     %eax,%ebx               # backup rounds
-       shl     \$7,%rax                # 128 bytes per inner round key
-       sub     \$`128-32`,%rax         # size of bit-sliced key schedule
-       sub     %rax,%rsp
-       mov     %rsp,%rax               # pass key schedule
-       mov     $key,%rcx               # pass key
-       mov     %ebx,%r10d              # pass rounds
-       call    _bsaes_key_convert
-       pxor    (%rsp),%xmm7            # fix up 0 round key
-       movdqa  %xmm6,(%rax)            # save last round key
-       movdqa  %xmm7,(%rsp)
-
-       sub     \$8,$len
-.Lecb_dec_loop:
-       movdqu  0x00($inp), @XMM[0]     # load input
-       movdqu  0x10($inp), @XMM[1]
-       movdqu  0x20($inp), @XMM[2]
-       movdqu  0x30($inp), @XMM[3]
-       movdqu  0x40($inp), @XMM[4]
-       movdqu  0x50($inp), @XMM[5]
-       mov     %rsp, %rax              # pass key schedule
-       movdqu  0x60($inp), @XMM[6]
-       mov     %ebx,%r10d              # pass rounds
-       movdqu  0x70($inp), @XMM[7]
-       lea     0x80($inp), $inp
-
-       call    _bsaes_decrypt8
-
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[3], 0x60($out)
-       movdqu  @XMM[5], 0x70($out)
-       lea     0x80($out), $out
-       sub     \$8,$len
-       jnc     .Lecb_dec_loop
-
-       add     \$8,$len
-       jz      .Lecb_dec_done
-
-       movdqu  0x00($inp), @XMM[0]     # load input
-       mov     %rsp, %rax              # pass key schedule
-       mov     %ebx,%r10d              # pass rounds
-       cmp     \$2,$len
-       jb      .Lecb_dec_one
-       movdqu  0x10($inp), @XMM[1]
-       je      .Lecb_dec_two
-       movdqu  0x20($inp), @XMM[2]
-       cmp     \$4,$len
-       jb      .Lecb_dec_three
-       movdqu  0x30($inp), @XMM[3]
-       je      .Lecb_dec_four
-       movdqu  0x40($inp), @XMM[4]
-       cmp     \$6,$len
-       jb      .Lecb_dec_five
-       movdqu  0x50($inp), @XMM[5]
-       je      .Lecb_dec_six
-       movdqu  0x60($inp), @XMM[6]
-       call    _bsaes_decrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[3], 0x60($out)
-       jmp     .Lecb_dec_done
-.align 16
-.Lecb_dec_six:
-       call    _bsaes_decrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       jmp     .Lecb_dec_done
-.align 16
-.Lecb_dec_five:
-       call    _bsaes_decrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       jmp     .Lecb_dec_done
-.align 16
-.Lecb_dec_four:
-       call    _bsaes_decrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       jmp     .Lecb_dec_done
-.align 16
-.Lecb_dec_three:
-       call    _bsaes_decrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       jmp     .Lecb_dec_done
-.align 16
-.Lecb_dec_two:
-       call    _bsaes_decrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       jmp     .Lecb_dec_done
-.align 16
-.Lecb_dec_one:
-       call    _bsaes_decrypt8
-       movdqu  @XMM[0], 0x00($out)     # write output
-       jmp     .Lecb_dec_done
-.align 16
-.Lecb_dec_short:
-       lea     ($inp), $arg1
-       lea     ($out), $arg2
-       lea     ($key), $arg3
-       call    asm_AES_decrypt
-       lea     16($inp), $inp
-       lea     16($out), $out
-       dec     $len
-       jnz     .Lecb_dec_short
-
-.Lecb_dec_done:
-       lea     (%rsp),%rax
-       pxor    %xmm0, %xmm0
-.Lecb_dec_bzero:                       # wipe key schedule [if any]
-       movdqa  %xmm0, 0x00(%rax)
-       movdqa  %xmm0, 0x10(%rax)
-       lea     0x20(%rax), %rax
-       cmp     %rax, %rbp
-       jb      .Lecb_dec_bzero
-
-       lea     0x78(%rbp),%rax
-.cfi_def_cfa   %rax,8
-___
-$code.=<<___ if ($win64);
-       movaps  0x40(%rbp), %xmm6
-       movaps  0x50(%rbp), %xmm7
-       movaps  0x60(%rbp), %xmm8
-       movaps  0x70(%rbp), %xmm9
-       movaps  0x80(%rbp), %xmm10
-       movaps  0x90(%rbp), %xmm11
-       movaps  0xa0(%rbp), %xmm12
-       movaps  0xb0(%rbp), %xmm13
-       movaps  0xc0(%rbp), %xmm14
-       movaps  0xd0(%rbp), %xmm15
-       lea     0xa0(%rax), %rax
-.Lecb_dec_tail:
-___
-$code.=<<___;
-       mov     -48(%rax), %r15
-.cfi_restore   %r15
-       mov     -40(%rax), %r14
-.cfi_restore   %r14
-       mov     -32(%rax), %r13
-.cfi_restore   %r13
-       mov     -24(%rax), %r12
-.cfi_restore   %r12
-       mov     -16(%rax), %rbx
-.cfi_restore   %rbx
-       mov     -8(%rax), %rbp
-.cfi_restore   %rbp
-       lea     (%rax), %rsp            # restore %rsp
-.cfi_def_cfa_register  %rsp
-.Lecb_dec_epilogue:
-       ret
-.cfi_endproc
-.size  bsaes_ecb_decrypt_blocks,.-bsaes_ecb_decrypt_blocks
-___
-}
-$code.=<<___;
-.extern        asm_AES_cbc_encrypt
-.globl bsaes_cbc_encrypt
-.type  bsaes_cbc_encrypt,\@abi-omnipotent
-.align 16
-bsaes_cbc_encrypt:
-.cfi_startproc
-___
-$code.=<<___ if ($win64);
-       mov     48(%rsp),$arg6          # pull direction flag
-___
-$code.=<<___;
-       cmp     \$0,$arg6
-       jne     asm_AES_cbc_encrypt
-       cmp     \$128,$arg3
-       jb      asm_AES_cbc_encrypt
-
-       mov     %rsp, %rax
-.Lcbc_dec_prologue:
-       push    %rbp
-.cfi_push      %rbp
-       push    %rbx
-.cfi_push      %rbx
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-       lea     -0x48(%rsp), %rsp
-.cfi_adjust_cfa_offset 0x48
-___
-$code.=<<___ if ($win64);
-       mov     0xa0(%rsp),$arg5        # pull ivp
-       lea     -0xa0(%rsp), %rsp
-       movaps  %xmm6, 0x40(%rsp)
-       movaps  %xmm7, 0x50(%rsp)
-       movaps  %xmm8, 0x60(%rsp)
-       movaps  %xmm9, 0x70(%rsp)
-       movaps  %xmm10, 0x80(%rsp)
-       movaps  %xmm11, 0x90(%rsp)
-       movaps  %xmm12, 0xa0(%rsp)
-       movaps  %xmm13, 0xb0(%rsp)
-       movaps  %xmm14, 0xc0(%rsp)
-       movaps  %xmm15, 0xd0(%rsp)
-.Lcbc_dec_body:
-___
-$code.=<<___;
-       mov     %rsp, %rbp              # backup %rsp
-.cfi_def_cfa_register  %rbp
-       mov     240($arg4), %eax        # rounds
-       mov     $arg1, $inp             # backup arguments
-       mov     $arg2, $out
-       mov     $arg3, $len
-       mov     $arg4, $key
-       mov     $arg5, %rbx
-       shr     \$4, $len               # bytes to blocks
-
-       mov     %eax, %edx              # rounds
-       shl     \$7, %rax               # 128 bytes per inner round key
-       sub     \$`128-32`, %rax        # size of bit-sliced key schedule
-       sub     %rax, %rsp
-
-       mov     %rsp, %rax              # pass key schedule
-       mov     $key, %rcx              # pass key
-       mov     %edx, %r10d             # pass rounds
-       call    _bsaes_key_convert
-       pxor    (%rsp),%xmm7            # fix up 0 round key
-       movdqa  %xmm6,(%rax)            # save last round key
-       movdqa  %xmm7,(%rsp)
-
-       movdqu  (%rbx), @XMM[15]        # load IV
-       sub     \$8,$len
-.Lcbc_dec_loop:
-       movdqu  0x00($inp), @XMM[0]     # load input
-       movdqu  0x10($inp), @XMM[1]
-       movdqu  0x20($inp), @XMM[2]
-       movdqu  0x30($inp), @XMM[3]
-       movdqu  0x40($inp), @XMM[4]
-       movdqu  0x50($inp), @XMM[5]
-       mov     %rsp, %rax              # pass key schedule
-       movdqu  0x60($inp), @XMM[6]
-       mov     %edx,%r10d              # pass rounds
-       movdqu  0x70($inp), @XMM[7]
-       movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
-
-       call    _bsaes_decrypt8
-
-       pxor    0x20(%rbp), @XMM[0]     # ^= IV
-       movdqu  0x00($inp), @XMM[8]     # re-load input
-       movdqu  0x10($inp), @XMM[9]
-       pxor    @XMM[8], @XMM[1]
-       movdqu  0x20($inp), @XMM[10]
-       pxor    @XMM[9], @XMM[6]
-       movdqu  0x30($inp), @XMM[11]
-       pxor    @XMM[10], @XMM[4]
-       movdqu  0x40($inp), @XMM[12]
-       pxor    @XMM[11], @XMM[2]
-       movdqu  0x50($inp), @XMM[13]
-       pxor    @XMM[12], @XMM[7]
-       movdqu  0x60($inp), @XMM[14]
-       pxor    @XMM[13], @XMM[3]
-       movdqu  0x70($inp), @XMM[15]    # IV
-       pxor    @XMM[14], @XMM[5]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       lea     0x80($inp), $inp
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[3], 0x60($out)
-       movdqu  @XMM[5], 0x70($out)
-       lea     0x80($out), $out
-       sub     \$8,$len
-       jnc     .Lcbc_dec_loop
-
-       add     \$8,$len
-       jz      .Lcbc_dec_done
-
-       movdqu  0x00($inp), @XMM[0]     # load input
-       mov     %rsp, %rax              # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-       cmp     \$2,$len
-       jb      .Lcbc_dec_one
-       movdqu  0x10($inp), @XMM[1]
-       je      .Lcbc_dec_two
-       movdqu  0x20($inp), @XMM[2]
-       cmp     \$4,$len
-       jb      .Lcbc_dec_three
-       movdqu  0x30($inp), @XMM[3]
-       je      .Lcbc_dec_four
-       movdqu  0x40($inp), @XMM[4]
-       cmp     \$6,$len
-       jb      .Lcbc_dec_five
-       movdqu  0x50($inp), @XMM[5]
-       je      .Lcbc_dec_six
-       movdqu  0x60($inp), @XMM[6]
-       movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
-       call    _bsaes_decrypt8
-       pxor    0x20(%rbp), @XMM[0]     # ^= IV
-       movdqu  0x00($inp), @XMM[8]     # re-load input
-       movdqu  0x10($inp), @XMM[9]
-       pxor    @XMM[8], @XMM[1]
-       movdqu  0x20($inp), @XMM[10]
-       pxor    @XMM[9], @XMM[6]
-       movdqu  0x30($inp), @XMM[11]
-       pxor    @XMM[10], @XMM[4]
-       movdqu  0x40($inp), @XMM[12]
-       pxor    @XMM[11], @XMM[2]
-       movdqu  0x50($inp), @XMM[13]
-       pxor    @XMM[12], @XMM[7]
-       movdqu  0x60($inp), @XMM[15]    # IV
-       pxor    @XMM[13], @XMM[3]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[3], 0x60($out)
-       jmp     .Lcbc_dec_done
-.align 16
-.Lcbc_dec_six:
-       movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
-       call    _bsaes_decrypt8
-       pxor    0x20(%rbp), @XMM[0]     # ^= IV
-       movdqu  0x00($inp), @XMM[8]     # re-load input
-       movdqu  0x10($inp), @XMM[9]
-       pxor    @XMM[8], @XMM[1]
-       movdqu  0x20($inp), @XMM[10]
-       pxor    @XMM[9], @XMM[6]
-       movdqu  0x30($inp), @XMM[11]
-       pxor    @XMM[10], @XMM[4]
-       movdqu  0x40($inp), @XMM[12]
-       pxor    @XMM[11], @XMM[2]
-       movdqu  0x50($inp), @XMM[15]    # IV
-       pxor    @XMM[12], @XMM[7]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       jmp     .Lcbc_dec_done
-.align 16
-.Lcbc_dec_five:
-       movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
-       call    _bsaes_decrypt8
-       pxor    0x20(%rbp), @XMM[0]     # ^= IV
-       movdqu  0x00($inp), @XMM[8]     # re-load input
-       movdqu  0x10($inp), @XMM[9]
-       pxor    @XMM[8], @XMM[1]
-       movdqu  0x20($inp), @XMM[10]
-       pxor    @XMM[9], @XMM[6]
-       movdqu  0x30($inp), @XMM[11]
-       pxor    @XMM[10], @XMM[4]
-       movdqu  0x40($inp), @XMM[15]    # IV
-       pxor    @XMM[11], @XMM[2]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       jmp     .Lcbc_dec_done
-.align 16
-.Lcbc_dec_four:
-       movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
-       call    _bsaes_decrypt8
-       pxor    0x20(%rbp), @XMM[0]     # ^= IV
-       movdqu  0x00($inp), @XMM[8]     # re-load input
-       movdqu  0x10($inp), @XMM[9]
-       pxor    @XMM[8], @XMM[1]
-       movdqu  0x20($inp), @XMM[10]
-       pxor    @XMM[9], @XMM[6]
-       movdqu  0x30($inp), @XMM[15]    # IV
-       pxor    @XMM[10], @XMM[4]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       jmp     .Lcbc_dec_done
-.align 16
-.Lcbc_dec_three:
-       movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
-       call    _bsaes_decrypt8
-       pxor    0x20(%rbp), @XMM[0]     # ^= IV
-       movdqu  0x00($inp), @XMM[8]     # re-load input
-       movdqu  0x10($inp), @XMM[9]
-       pxor    @XMM[8], @XMM[1]
-       movdqu  0x20($inp), @XMM[15]    # IV
-       pxor    @XMM[9], @XMM[6]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       jmp     .Lcbc_dec_done
-.align 16
-.Lcbc_dec_two:
-       movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
-       call    _bsaes_decrypt8
-       pxor    0x20(%rbp), @XMM[0]     # ^= IV
-       movdqu  0x00($inp), @XMM[8]     # re-load input
-       movdqu  0x10($inp), @XMM[15]    # IV
-       pxor    @XMM[8], @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       jmp     .Lcbc_dec_done
-.align 16
-.Lcbc_dec_one:
-       lea     ($inp), $arg1
-       lea     0x20(%rbp), $arg2       # buffer output
-       lea     ($key), $arg3
-       call    asm_AES_decrypt         # doesn't touch %xmm
-       pxor    0x20(%rbp), @XMM[15]    # ^= IV
-       movdqu  @XMM[15], ($out)        # write output
-       movdqa  @XMM[0], @XMM[15]       # IV
-
-.Lcbc_dec_done:
-       movdqu  @XMM[15], (%rbx)        # return IV
-       lea     (%rsp), %rax
-       pxor    %xmm0, %xmm0
-.Lcbc_dec_bzero:                       # wipe key schedule [if any]
-       movdqa  %xmm0, 0x00(%rax)
-       movdqa  %xmm0, 0x10(%rax)
-       lea     0x20(%rax), %rax
-       cmp     %rax, %rbp
-       ja      .Lcbc_dec_bzero
-
-       lea     0x78(%rbp),%rax
-.cfi_def_cfa   %rax,8
-___
-$code.=<<___ if ($win64);
-       movaps  0x40(%rbp), %xmm6
-       movaps  0x50(%rbp), %xmm7
-       movaps  0x60(%rbp), %xmm8
-       movaps  0x70(%rbp), %xmm9
-       movaps  0x80(%rbp), %xmm10
-       movaps  0x90(%rbp), %xmm11
-       movaps  0xa0(%rbp), %xmm12
-       movaps  0xb0(%rbp), %xmm13
-       movaps  0xc0(%rbp), %xmm14
-       movaps  0xd0(%rbp), %xmm15
-       lea     0xa0(%rax), %rax
-.Lcbc_dec_tail:
-___
-$code.=<<___;
-       mov     -48(%rax), %r15
-.cfi_restore   %r15
-       mov     -40(%rax), %r14
-.cfi_restore   %r14
-       mov     -32(%rax), %r13
-.cfi_restore   %r13
-       mov     -24(%rax), %r12
-.cfi_restore   %r12
-       mov     -16(%rax), %rbx
-.cfi_restore   %rbx
-       mov     -8(%rax), %rbp
-.cfi_restore   %rbp
-       lea     (%rax), %rsp            # restore %rsp
-.cfi_def_cfa_register  %rsp
-.Lcbc_dec_epilogue:
-       ret
-.cfi_endproc
-.size  bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
-
-.globl bsaes_ctr32_encrypt_blocks
-.type  bsaes_ctr32_encrypt_blocks,\@abi-omnipotent
-.align 16
-bsaes_ctr32_encrypt_blocks:
-.cfi_startproc
-       mov     %rsp, %rax
-.Lctr_enc_prologue:
-       push    %rbp
-.cfi_push      %rbp
-       push    %rbx
-.cfi_push      %rbx
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-       lea     -0x48(%rsp), %rsp
-.cfi_adjust_cfa_offset 0x48
-___
-$code.=<<___ if ($win64);
-       mov     0xa0(%rsp),$arg5        # pull ivp
-       lea     -0xa0(%rsp), %rsp
-       movaps  %xmm6, 0x40(%rsp)
-       movaps  %xmm7, 0x50(%rsp)
-       movaps  %xmm8, 0x60(%rsp)
-       movaps  %xmm9, 0x70(%rsp)
-       movaps  %xmm10, 0x80(%rsp)
-       movaps  %xmm11, 0x90(%rsp)
-       movaps  %xmm12, 0xa0(%rsp)
-       movaps  %xmm13, 0xb0(%rsp)
-       movaps  %xmm14, 0xc0(%rsp)
-       movaps  %xmm15, 0xd0(%rsp)
-.Lctr_enc_body:
-___
-$code.=<<___;
-       mov     %rsp, %rbp              # backup %rsp
-.cfi_def_cfa_register  %rbp
-       movdqu  ($arg5), %xmm0          # load counter
-       mov     240($arg4), %eax        # rounds
-       mov     $arg1, $inp             # backup arguments
-       mov     $arg2, $out
-       mov     $arg3, $len
-       mov     $arg4, $key
-       movdqa  %xmm0, 0x20(%rbp)       # copy counter
-       cmp     \$8, $arg3
-       jb      .Lctr_enc_short
-
-       mov     %eax, %ebx              # rounds
-       shl     \$7, %rax               # 128 bytes per inner round key
-       sub     \$`128-32`, %rax        # size of bit-sliced key schedule
-       sub     %rax, %rsp
-
-       mov     %rsp, %rax              # pass key schedule
-       mov     $key, %rcx              # pass key
-       mov     %ebx, %r10d             # pass rounds
-       call    _bsaes_key_convert
-       pxor    %xmm6,%xmm7             # fix up last round key
-       movdqa  %xmm7,(%rax)            # save last round key
-
-       movdqa  (%rsp), @XMM[9]         # load round0 key
-       lea     .LADD1(%rip), %r11
-       movdqa  0x20(%rbp), @XMM[0]     # counter copy
-       movdqa  -0x20(%r11), @XMM[8]    # .LSWPUP
-       pshufb  @XMM[8], @XMM[9]        # byte swap upper part
-       pshufb  @XMM[8], @XMM[0]
-       movdqa  @XMM[9], (%rsp)         # save adjusted round0 key
-       jmp     .Lctr_enc_loop
-.align 16
-.Lctr_enc_loop:
-       movdqa  @XMM[0], 0x20(%rbp)     # save counter
-       movdqa  @XMM[0], @XMM[1]        # prepare 8 counter values
-       movdqa  @XMM[0], @XMM[2]
-       paddd   0x00(%r11), @XMM[1]     # .LADD1
-       movdqa  @XMM[0], @XMM[3]
-       paddd   0x10(%r11), @XMM[2]     # .LADD2
-       movdqa  @XMM[0], @XMM[4]
-       paddd   0x20(%r11), @XMM[3]     # .LADD3
-       movdqa  @XMM[0], @XMM[5]
-       paddd   0x30(%r11), @XMM[4]     # .LADD4
-       movdqa  @XMM[0], @XMM[6]
-       paddd   0x40(%r11), @XMM[5]     # .LADD5
-       movdqa  @XMM[0], @XMM[7]
-       paddd   0x50(%r11), @XMM[6]     # .LADD6
-       paddd   0x60(%r11), @XMM[7]     # .LADD7
-
-       # Borrow prologue from _bsaes_encrypt8 to use the opportunity
-       # to flip byte order in 32-bit counter
-       movdqa  (%rsp), @XMM[9]         # round 0 key
-       lea     0x10(%rsp), %rax        # pass key schedule
-       movdqa  -0x10(%r11), @XMM[8]    # .LSWPUPM0SR
-       pxor    @XMM[9], @XMM[0]        # xor with round0 key
-       pxor    @XMM[9], @XMM[1]
-       pxor    @XMM[9], @XMM[2]
-       pxor    @XMM[9], @XMM[3]
-        pshufb @XMM[8], @XMM[0]
-        pshufb @XMM[8], @XMM[1]
-       pxor    @XMM[9], @XMM[4]
-       pxor    @XMM[9], @XMM[5]
-        pshufb @XMM[8], @XMM[2]
-        pshufb @XMM[8], @XMM[3]
-       pxor    @XMM[9], @XMM[6]
-       pxor    @XMM[9], @XMM[7]
-        pshufb @XMM[8], @XMM[4]
-        pshufb @XMM[8], @XMM[5]
-        pshufb @XMM[8], @XMM[6]
-        pshufb @XMM[8], @XMM[7]
-       lea     .LBS0(%rip), %r11       # constants table
-       mov     %ebx,%r10d              # pass rounds
-
-       call    _bsaes_encrypt8_bitslice
-
-       sub     \$8,$len
-       jc      .Lctr_enc_loop_done
-
-       movdqu  0x00($inp), @XMM[8]     # load input
-       movdqu  0x10($inp), @XMM[9]
-       movdqu  0x20($inp), @XMM[10]
-       movdqu  0x30($inp), @XMM[11]
-       movdqu  0x40($inp), @XMM[12]
-       movdqu  0x50($inp), @XMM[13]
-       movdqu  0x60($inp), @XMM[14]
-       movdqu  0x70($inp), @XMM[15]
-       lea     0x80($inp),$inp
-       pxor    @XMM[0], @XMM[8]
-       movdqa  0x20(%rbp), @XMM[0]     # load counter
-       pxor    @XMM[9], @XMM[1]
-       movdqu  @XMM[8], 0x00($out)     # write output
-       pxor    @XMM[10], @XMM[4]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    @XMM[11], @XMM[6]
-       movdqu  @XMM[4], 0x20($out)
-       pxor    @XMM[12], @XMM[3]
-       movdqu  @XMM[6], 0x30($out)
-       pxor    @XMM[13], @XMM[7]
-       movdqu  @XMM[3], 0x40($out)
-       pxor    @XMM[14], @XMM[2]
-       movdqu  @XMM[7], 0x50($out)
-       pxor    @XMM[15], @XMM[5]
-       movdqu  @XMM[2], 0x60($out)
-       lea     .LADD1(%rip), %r11
-       movdqu  @XMM[5], 0x70($out)
-       lea     0x80($out), $out
-       paddd   0x70(%r11), @XMM[0]     # .LADD8
-       jnz     .Lctr_enc_loop
-
-       jmp     .Lctr_enc_done
-.align 16
-.Lctr_enc_loop_done:
-       add     \$8, $len
-       movdqu  0x00($inp), @XMM[8]     # load input
-       pxor    @XMM[8], @XMM[0]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       cmp     \$2,$len
-       jb      .Lctr_enc_done
-       movdqu  0x10($inp), @XMM[9]
-       pxor    @XMM[9], @XMM[1]
-       movdqu  @XMM[1], 0x10($out)
-       je      .Lctr_enc_done
-       movdqu  0x20($inp), @XMM[10]
-       pxor    @XMM[10], @XMM[4]
-       movdqu  @XMM[4], 0x20($out)
-       cmp     \$4,$len
-       jb      .Lctr_enc_done
-       movdqu  0x30($inp), @XMM[11]
-       pxor    @XMM[11], @XMM[6]
-       movdqu  @XMM[6], 0x30($out)
-       je      .Lctr_enc_done
-       movdqu  0x40($inp), @XMM[12]
-       pxor    @XMM[12], @XMM[3]
-       movdqu  @XMM[3], 0x40($out)
-       cmp     \$6,$len
-       jb      .Lctr_enc_done
-       movdqu  0x50($inp), @XMM[13]
-       pxor    @XMM[13], @XMM[7]
-       movdqu  @XMM[7], 0x50($out)
-       je      .Lctr_enc_done
-       movdqu  0x60($inp), @XMM[14]
-       pxor    @XMM[14], @XMM[2]
-       movdqu  @XMM[2], 0x60($out)
-       jmp     .Lctr_enc_done
-
-.align 16
-.Lctr_enc_short:
-       lea     0x20(%rbp), $arg1
-       lea     0x30(%rbp), $arg2
-       lea     ($key), $arg3
-       call    asm_AES_encrypt
-       movdqu  ($inp), @XMM[1]
-       lea     16($inp), $inp
-       mov     0x2c(%rbp), %eax        # load 32-bit counter
-       bswap   %eax
-       pxor    0x30(%rbp), @XMM[1]
-       inc     %eax                    # increment
-       movdqu  @XMM[1], ($out)
-       bswap   %eax
-       lea     16($out), $out
-       mov     %eax, 0x2c(%rsp)        # save 32-bit counter
-       dec     $len
-       jnz     .Lctr_enc_short
-
-.Lctr_enc_done:
-       lea     (%rsp), %rax
-       pxor    %xmm0, %xmm0
-.Lctr_enc_bzero:                       # wipe key schedule [if any]
-       movdqa  %xmm0, 0x00(%rax)
-       movdqa  %xmm0, 0x10(%rax)
-       lea     0x20(%rax), %rax
-       cmp     %rax, %rbp
-       ja      .Lctr_enc_bzero
-
-       lea     0x78(%rbp),%rax
-.cfi_def_cfa   %rax,8
-___
-$code.=<<___ if ($win64);
-       movaps  0x40(%rbp), %xmm6
-       movaps  0x50(%rbp), %xmm7
-       movaps  0x60(%rbp), %xmm8
-       movaps  0x70(%rbp), %xmm9
-       movaps  0x80(%rbp), %xmm10
-       movaps  0x90(%rbp), %xmm11
-       movaps  0xa0(%rbp), %xmm12
-       movaps  0xb0(%rbp), %xmm13
-       movaps  0xc0(%rbp), %xmm14
-       movaps  0xd0(%rbp), %xmm15
-       lea     0xa0(%rax), %rax
-.Lctr_enc_tail:
-___
-$code.=<<___;
-       mov     -48(%rax), %r15
-.cfi_restore   %r15
-       mov     -40(%rax), %r14
-.cfi_restore   %r14
-       mov     -32(%rax), %r13
-.cfi_restore   %r13
-       mov     -24(%rax), %r12
-.cfi_restore   %r12
-       mov     -16(%rax), %rbx
-.cfi_restore   %rbx
-       mov     -8(%rax), %rbp
-.cfi_restore   %rbp
-       lea     (%rax), %rsp            # restore %rsp
-.cfi_def_cfa_register  %rsp
-.Lctr_enc_epilogue:
-       ret
-.cfi_endproc
-.size  bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
-___
-######################################################################
-# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len,
-#      const AES_KEY *key1, const AES_KEY *key2,
-#      const unsigned char iv[16]);
-#
-my ($twmask,$twres,$twtmp)=@XMM[13..15];
-$arg6=~s/d$//;
-
-$code.=<<___;
-.globl bsaes_xts_encrypt
-.type  bsaes_xts_encrypt,\@abi-omnipotent
-.align 16
-bsaes_xts_encrypt:
-.cfi_startproc
-       mov     %rsp, %rax
-.Lxts_enc_prologue:
-       push    %rbp
-.cfi_push      %rbp
-       push    %rbx
-.cfi_push      %rbx
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-       lea     -0x48(%rsp), %rsp
-.cfi_adjust_cfa_offset 0x48
-___
-$code.=<<___ if ($win64);
-       mov     0xa0(%rsp),$arg5        # pull key2
-       mov     0xa8(%rsp),$arg6        # pull ivp
-       lea     -0xa0(%rsp), %rsp
-       movaps  %xmm6, 0x40(%rsp)
-       movaps  %xmm7, 0x50(%rsp)
-       movaps  %xmm8, 0x60(%rsp)
-       movaps  %xmm9, 0x70(%rsp)
-       movaps  %xmm10, 0x80(%rsp)
-       movaps  %xmm11, 0x90(%rsp)
-       movaps  %xmm12, 0xa0(%rsp)
-       movaps  %xmm13, 0xb0(%rsp)
-       movaps  %xmm14, 0xc0(%rsp)
-       movaps  %xmm15, 0xd0(%rsp)
-.Lxts_enc_body:
-___
-$code.=<<___;
-       mov     %rsp, %rbp              # backup %rsp
-.cfi_def_cfa_register  %rbp
-       mov     $arg1, $inp             # backup arguments
-       mov     $arg2, $out
-       mov     $arg3, $len
-       mov     $arg4, $key
-
-       lea     ($arg6), $arg1
-       lea     0x20(%rbp), $arg2
-       lea     ($arg5), $arg3
-       call    asm_AES_encrypt         # generate initial tweak
-
-       mov     240($key), %eax         # rounds
-       mov     $len, %rbx              # backup $len
-
-       mov     %eax, %edx              # rounds
-       shl     \$7, %rax               # 128 bytes per inner round key
-       sub     \$`128-32`, %rax        # size of bit-sliced key schedule
-       sub     %rax, %rsp
-
-       mov     %rsp, %rax              # pass key schedule
-       mov     $key, %rcx              # pass key
-       mov     %edx, %r10d             # pass rounds
-       call    _bsaes_key_convert
-       pxor    %xmm6, %xmm7            # fix up last round key
-       movdqa  %xmm7, (%rax)           # save last round key
-
-       and     \$-16, $len
-       sub     \$0x80, %rsp            # place for tweak[8]
-       movdqa  0x20(%rbp), @XMM[7]     # initial tweak
-
-       pxor    $twtmp, $twtmp
-       movdqa  .Lxts_magic(%rip), $twmask
-       pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
-
-       sub     \$0x80, $len
-       jc      .Lxts_enc_short
-       jmp     .Lxts_enc_loop
-
-.align 16
-.Lxts_enc_loop:
-___
-    for ($i=0;$i<7;$i++) {
-    $code.=<<___;
-       pshufd  \$0x13, $twtmp, $twres
-       pxor    $twtmp, $twtmp
-       movdqa  @XMM[7], @XMM[$i]
-       movdqa  @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
-       paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
-       pand    $twmask, $twres         # isolate carry and residue
-       pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
-       pxor    $twres, @XMM[7]
-___
-    $code.=<<___ if ($i>=1);
-       movdqu  `0x10*($i-1)`($inp), @XMM[8+$i-1]
-___
-    $code.=<<___ if ($i>=2);
-       pxor    @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
-___
-    }
-$code.=<<___;
-       movdqu  0x60($inp), @XMM[8+6]
-       pxor    @XMM[8+5], @XMM[5]
-       movdqu  0x70($inp), @XMM[8+7]
-       lea     0x80($inp), $inp
-       movdqa  @XMM[7], 0x70(%rsp)
-       pxor    @XMM[8+6], @XMM[6]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       pxor    @XMM[8+7], @XMM[7]
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_encrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[4]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[6]
-       movdqu  @XMM[4], 0x20($out)
-       pxor    0x40(%rsp), @XMM[3]
-       movdqu  @XMM[6], 0x30($out)
-       pxor    0x50(%rsp), @XMM[7]
-       movdqu  @XMM[3], 0x40($out)
-       pxor    0x60(%rsp), @XMM[2]
-       movdqu  @XMM[7], 0x50($out)
-       pxor    0x70(%rsp), @XMM[5]
-       movdqu  @XMM[2], 0x60($out)
-       movdqu  @XMM[5], 0x70($out)
-       lea     0x80($out), $out
-
-       movdqa  0x70(%rsp), @XMM[7]     # prepare next iteration tweak
-       pxor    $twtmp, $twtmp
-       movdqa  .Lxts_magic(%rip), $twmask
-       pcmpgtd @XMM[7], $twtmp
-       pshufd  \$0x13, $twtmp, $twres
-       pxor    $twtmp, $twtmp
-       paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
-       pand    $twmask, $twres         # isolate carry and residue
-       pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
-       pxor    $twres, @XMM[7]
-
-       sub     \$0x80,$len
-       jnc     .Lxts_enc_loop
-
-.Lxts_enc_short:
-       add     \$0x80, $len
-       jz      .Lxts_enc_done
-___
-    for ($i=0;$i<7;$i++) {
-    $code.=<<___;
-       pshufd  \$0x13, $twtmp, $twres
-       pxor    $twtmp, $twtmp
-       movdqa  @XMM[7], @XMM[$i]
-       movdqa  @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
-       paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
-       pand    $twmask, $twres         # isolate carry and residue
-       pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
-       pxor    $twres, @XMM[7]
-___
-    $code.=<<___ if ($i>=1);
-       movdqu  `0x10*($i-1)`($inp), @XMM[8+$i-1]
-       cmp     \$`0x10*$i`,$len
-       je      .Lxts_enc_$i
-___
-    $code.=<<___ if ($i>=2);
-       pxor    @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
-___
-    }
-$code.=<<___;
-       movdqu  0x60($inp), @XMM[8+6]
-       pxor    @XMM[8+5], @XMM[5]
-       movdqa  @XMM[7], 0x70(%rsp)
-       lea     0x70($inp), $inp
-       pxor    @XMM[8+6], @XMM[6]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_encrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[4]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[6]
-       movdqu  @XMM[4], 0x20($out)
-       pxor    0x40(%rsp), @XMM[3]
-       movdqu  @XMM[6], 0x30($out)
-       pxor    0x50(%rsp), @XMM[7]
-       movdqu  @XMM[3], 0x40($out)
-       pxor    0x60(%rsp), @XMM[2]
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[2], 0x60($out)
-       lea     0x70($out), $out
-
-       movdqa  0x70(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_enc_done
-.align 16
-.Lxts_enc_6:
-       pxor    @XMM[8+4], @XMM[4]
-       lea     0x60($inp), $inp
-       pxor    @XMM[8+5], @XMM[5]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_encrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[4]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[6]
-       movdqu  @XMM[4], 0x20($out)
-       pxor    0x40(%rsp), @XMM[3]
-       movdqu  @XMM[6], 0x30($out)
-       pxor    0x50(%rsp), @XMM[7]
-       movdqu  @XMM[3], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       lea     0x60($out), $out
-
-       movdqa  0x60(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_enc_done
-.align 16
-.Lxts_enc_5:
-       pxor    @XMM[8+3], @XMM[3]
-       lea     0x50($inp), $inp
-       pxor    @XMM[8+4], @XMM[4]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_encrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[4]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[6]
-       movdqu  @XMM[4], 0x20($out)
-       pxor    0x40(%rsp), @XMM[3]
-       movdqu  @XMM[6], 0x30($out)
-       movdqu  @XMM[3], 0x40($out)
-       lea     0x50($out), $out
-
-       movdqa  0x50(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_enc_done
-.align 16
-.Lxts_enc_4:
-       pxor    @XMM[8+2], @XMM[2]
-       lea     0x40($inp), $inp
-       pxor    @XMM[8+3], @XMM[3]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_encrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[4]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[6]
-       movdqu  @XMM[4], 0x20($out)
-       movdqu  @XMM[6], 0x30($out)
-       lea     0x40($out), $out
-
-       movdqa  0x40(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_enc_done
-.align 16
-.Lxts_enc_3:
-       pxor    @XMM[8+1], @XMM[1]
-       lea     0x30($inp), $inp
-       pxor    @XMM[8+2], @XMM[2]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_encrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[4]
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[4], 0x20($out)
-       lea     0x30($out), $out
-
-       movdqa  0x30(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_enc_done
-.align 16
-.Lxts_enc_2:
-       pxor    @XMM[8+0], @XMM[0]
-       lea     0x20($inp), $inp
-       pxor    @XMM[8+1], @XMM[1]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_encrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       lea     0x20($out), $out
-
-       movdqa  0x20(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_enc_done
-.align 16
-.Lxts_enc_1:
-       pxor    @XMM[0], @XMM[8]
-       lea     0x10($inp), $inp
-       movdqa  @XMM[8], 0x20(%rbp)
-       lea     0x20(%rbp), $arg1
-       lea     0x20(%rbp), $arg2
-       lea     ($key), $arg3
-       call    asm_AES_encrypt         # doesn't touch %xmm
-       pxor    0x20(%rbp), @XMM[0]     # ^= tweak[]
-       #pxor   @XMM[8], @XMM[0]
-       #lea    0x80(%rsp), %rax        # pass key schedule
-       #mov    %edx, %r10d             # pass rounds
-       #call   _bsaes_encrypt8
-       #pxor   0x00(%rsp), @XMM[0]     # ^= tweak[]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       lea     0x10($out), $out
-
-       movdqa  0x10(%rsp), @XMM[7]     # next iteration tweak
-
-.Lxts_enc_done:
-       and     \$15, %ebx
-       jz      .Lxts_enc_ret
-       mov     $out, %rdx
-
-.Lxts_enc_steal:
-       movzb   ($inp), %eax
-       movzb   -16(%rdx), %ecx
-       lea     1($inp), $inp
-       mov     %al, -16(%rdx)
-       mov     %cl, 0(%rdx)
-       lea     1(%rdx), %rdx
-       sub     \$1,%ebx
-       jnz     .Lxts_enc_steal
-
-       movdqu  -16($out), @XMM[0]
-       lea     0x20(%rbp), $arg1
-       pxor    @XMM[7], @XMM[0]
-       lea     0x20(%rbp), $arg2
-       movdqa  @XMM[0], 0x20(%rbp)
-       lea     ($key), $arg3
-       call    asm_AES_encrypt         # doesn't touch %xmm
-       pxor    0x20(%rbp), @XMM[7]
-       movdqu  @XMM[7], -16($out)
-
-.Lxts_enc_ret:
-       lea     (%rsp), %rax
-       pxor    %xmm0, %xmm0
-.Lxts_enc_bzero:                       # wipe key schedule [if any]
-       movdqa  %xmm0, 0x00(%rax)
-       movdqa  %xmm0, 0x10(%rax)
-       lea     0x20(%rax), %rax
-       cmp     %rax, %rbp
-       ja      .Lxts_enc_bzero
-
-       lea     0x78(%rbp),%rax
-.cfi_def_cfa   %rax,8
-___
-$code.=<<___ if ($win64);
-       movaps  0x40(%rbp), %xmm6
-       movaps  0x50(%rbp), %xmm7
-       movaps  0x60(%rbp), %xmm8
-       movaps  0x70(%rbp), %xmm9
-       movaps  0x80(%rbp), %xmm10
-       movaps  0x90(%rbp), %xmm11
-       movaps  0xa0(%rbp), %xmm12
-       movaps  0xb0(%rbp), %xmm13
-       movaps  0xc0(%rbp), %xmm14
-       movaps  0xd0(%rbp), %xmm15
-       lea     0xa0(%rax), %rax
-.Lxts_enc_tail:
-___
-$code.=<<___;
-       mov     -48(%rax), %r15
-.cfi_restore   %r15
-       mov     -40(%rax), %r14
-.cfi_restore   %r14
-       mov     -32(%rax), %r13
-.cfi_restore   %r13
-       mov     -24(%rax), %r12
-.cfi_restore   %r12
-       mov     -16(%rax), %rbx
-.cfi_restore   %rbx
-       mov     -8(%rax), %rbp
-.cfi_restore   %rbp
-       lea     (%rax), %rsp            # restore %rsp
-.cfi_def_cfa_register  %rsp
-.Lxts_enc_epilogue:
-       ret
-.cfi_endproc
-.size  bsaes_xts_encrypt,.-bsaes_xts_encrypt
-
-.globl bsaes_xts_decrypt
-.type  bsaes_xts_decrypt,\@abi-omnipotent
-.align 16
-bsaes_xts_decrypt:
-.cfi_startproc
-       mov     %rsp, %rax
-.Lxts_dec_prologue:
-       push    %rbp
-.cfi_push      %rbp
-       push    %rbx
-.cfi_push      %rbx
-       push    %r12
-.cfi_push      %r12
-       push    %r13
-.cfi_push      %r13
-       push    %r14
-.cfi_push      %r14
-       push    %r15
-.cfi_push      %r15
-       lea     -0x48(%rsp), %rsp
-.cfi_adjust_cfa_offset 0x48
-___
-$code.=<<___ if ($win64);
-       mov     0xa0(%rsp),$arg5        # pull key2
-       mov     0xa8(%rsp),$arg6        # pull ivp
-       lea     -0xa0(%rsp), %rsp
-       movaps  %xmm6, 0x40(%rsp)
-       movaps  %xmm7, 0x50(%rsp)
-       movaps  %xmm8, 0x60(%rsp)
-       movaps  %xmm9, 0x70(%rsp)
-       movaps  %xmm10, 0x80(%rsp)
-       movaps  %xmm11, 0x90(%rsp)
-       movaps  %xmm12, 0xa0(%rsp)
-       movaps  %xmm13, 0xb0(%rsp)
-       movaps  %xmm14, 0xc0(%rsp)
-       movaps  %xmm15, 0xd0(%rsp)
-.Lxts_dec_body:
-___
-$code.=<<___;
-       mov     %rsp, %rbp              # backup %rsp
-       mov     $arg1, $inp             # backup arguments
-       mov     $arg2, $out
-       mov     $arg3, $len
-       mov     $arg4, $key
-
-       lea     ($arg6), $arg1
-       lea     0x20(%rbp), $arg2
-       lea     ($arg5), $arg3
-       call    asm_AES_encrypt         # generate initial tweak
-
-       mov     240($key), %eax         # rounds
-       mov     $len, %rbx              # backup $len
-
-       mov     %eax, %edx              # rounds
-       shl     \$7, %rax               # 128 bytes per inner round key
-       sub     \$`128-32`, %rax        # size of bit-sliced key schedule
-       sub     %rax, %rsp
-
-       mov     %rsp, %rax              # pass key schedule
-       mov     $key, %rcx              # pass key
-       mov     %edx, %r10d             # pass rounds
-       call    _bsaes_key_convert
-       pxor    (%rsp), %xmm7           # fix up round 0 key
-       movdqa  %xmm6, (%rax)           # save last round key
-       movdqa  %xmm7, (%rsp)
-
-       xor     %eax, %eax              # if ($len%16) len-=16;
-       and     \$-16, $len
-       test    \$15, %ebx
-       setnz   %al
-       shl     \$4, %rax
-       sub     %rax, $len
-
-       sub     \$0x80, %rsp            # place for tweak[8]
-       movdqa  0x20(%rbp), @XMM[7]     # initial tweak
-
-       pxor    $twtmp, $twtmp
-       movdqa  .Lxts_magic(%rip), $twmask
-       pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
-
-       sub     \$0x80, $len
-       jc      .Lxts_dec_short
-       jmp     .Lxts_dec_loop
-
-.align 16
-.Lxts_dec_loop:
-___
-    for ($i=0;$i<7;$i++) {
-    $code.=<<___;
-       pshufd  \$0x13, $twtmp, $twres
-       pxor    $twtmp, $twtmp
-       movdqa  @XMM[7], @XMM[$i]
-       movdqa  @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
-       paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
-       pand    $twmask, $twres         # isolate carry and residue
-       pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
-       pxor    $twres, @XMM[7]
-___
-    $code.=<<___ if ($i>=1);
-       movdqu  `0x10*($i-1)`($inp), @XMM[8+$i-1]
-___
-    $code.=<<___ if ($i>=2);
-       pxor    @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
-___
-    }
-$code.=<<___;
-       movdqu  0x60($inp), @XMM[8+6]
-       pxor    @XMM[8+5], @XMM[5]
-       movdqu  0x70($inp), @XMM[8+7]
-       lea     0x80($inp), $inp
-       movdqa  @XMM[7], 0x70(%rsp)
-       pxor    @XMM[8+6], @XMM[6]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       pxor    @XMM[8+7], @XMM[7]
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_decrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[6]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[4]
-       movdqu  @XMM[6], 0x20($out)
-       pxor    0x40(%rsp), @XMM[2]
-       movdqu  @XMM[4], 0x30($out)
-       pxor    0x50(%rsp), @XMM[7]
-       movdqu  @XMM[2], 0x40($out)
-       pxor    0x60(%rsp), @XMM[3]
-       movdqu  @XMM[7], 0x50($out)
-       pxor    0x70(%rsp), @XMM[5]
-       movdqu  @XMM[3], 0x60($out)
-       movdqu  @XMM[5], 0x70($out)
-       lea     0x80($out), $out
-
-       movdqa  0x70(%rsp), @XMM[7]     # prepare next iteration tweak
-       pxor    $twtmp, $twtmp
-       movdqa  .Lxts_magic(%rip), $twmask
-       pcmpgtd @XMM[7], $twtmp
-       pshufd  \$0x13, $twtmp, $twres
-       pxor    $twtmp, $twtmp
-       paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
-       pand    $twmask, $twres         # isolate carry and residue
-       pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
-       pxor    $twres, @XMM[7]
-
-       sub     \$0x80,$len
-       jnc     .Lxts_dec_loop
-
-.Lxts_dec_short:
-       add     \$0x80, $len
-       jz      .Lxts_dec_done
-___
-    for ($i=0;$i<7;$i++) {
-    $code.=<<___;
-       pshufd  \$0x13, $twtmp, $twres
-       pxor    $twtmp, $twtmp
-       movdqa  @XMM[7], @XMM[$i]
-       movdqa  @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
-       paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
-       pand    $twmask, $twres         # isolate carry and residue
-       pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
-       pxor    $twres, @XMM[7]
-___
-    $code.=<<___ if ($i>=1);
-       movdqu  `0x10*($i-1)`($inp), @XMM[8+$i-1]
-       cmp     \$`0x10*$i`,$len
-       je      .Lxts_dec_$i
-___
-    $code.=<<___ if ($i>=2);
-       pxor    @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
-___
-    }
-$code.=<<___;
-       movdqu  0x60($inp), @XMM[8+6]
-       pxor    @XMM[8+5], @XMM[5]
-       movdqa  @XMM[7], 0x70(%rsp)
-       lea     0x70($inp), $inp
-       pxor    @XMM[8+6], @XMM[6]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_decrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[6]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[4]
-       movdqu  @XMM[6], 0x20($out)
-       pxor    0x40(%rsp), @XMM[2]
-       movdqu  @XMM[4], 0x30($out)
-       pxor    0x50(%rsp), @XMM[7]
-       movdqu  @XMM[2], 0x40($out)
-       pxor    0x60(%rsp), @XMM[3]
-       movdqu  @XMM[7], 0x50($out)
-       movdqu  @XMM[3], 0x60($out)
-       lea     0x70($out), $out
-
-       movdqa  0x70(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_dec_done
-.align 16
-.Lxts_dec_6:
-       pxor    @XMM[8+4], @XMM[4]
-       lea     0x60($inp), $inp
-       pxor    @XMM[8+5], @XMM[5]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_decrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[6]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[4]
-       movdqu  @XMM[6], 0x20($out)
-       pxor    0x40(%rsp), @XMM[2]
-       movdqu  @XMM[4], 0x30($out)
-       pxor    0x50(%rsp), @XMM[7]
-       movdqu  @XMM[2], 0x40($out)
-       movdqu  @XMM[7], 0x50($out)
-       lea     0x60($out), $out
-
-       movdqa  0x60(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_dec_done
-.align 16
-.Lxts_dec_5:
-       pxor    @XMM[8+3], @XMM[3]
-       lea     0x50($inp), $inp
-       pxor    @XMM[8+4], @XMM[4]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_decrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[6]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[4]
-       movdqu  @XMM[6], 0x20($out)
-       pxor    0x40(%rsp), @XMM[2]
-       movdqu  @XMM[4], 0x30($out)
-       movdqu  @XMM[2], 0x40($out)
-       lea     0x50($out), $out
-
-       movdqa  0x50(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_dec_done
-.align 16
-.Lxts_dec_4:
-       pxor    @XMM[8+2], @XMM[2]
-       lea     0x40($inp), $inp
-       pxor    @XMM[8+3], @XMM[3]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_decrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[6]
-       movdqu  @XMM[1], 0x10($out)
-       pxor    0x30(%rsp), @XMM[4]
-       movdqu  @XMM[6], 0x20($out)
-       movdqu  @XMM[4], 0x30($out)
-       lea     0x40($out), $out
-
-       movdqa  0x40(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_dec_done
-.align 16
-.Lxts_dec_3:
-       pxor    @XMM[8+1], @XMM[1]
-       lea     0x30($inp), $inp
-       pxor    @XMM[8+2], @XMM[2]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_decrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       pxor    0x20(%rsp), @XMM[6]
-       movdqu  @XMM[1], 0x10($out)
-       movdqu  @XMM[6], 0x20($out)
-       lea     0x30($out), $out
-
-       movdqa  0x30(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_dec_done
-.align 16
-.Lxts_dec_2:
-       pxor    @XMM[8+0], @XMM[0]
-       lea     0x20($inp), $inp
-       pxor    @XMM[8+1], @XMM[1]
-       lea     0x80(%rsp), %rax        # pass key schedule
-       mov     %edx, %r10d             # pass rounds
-
-       call    _bsaes_decrypt8
-
-       pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
-       pxor    0x10(%rsp), @XMM[1]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       movdqu  @XMM[1], 0x10($out)
-       lea     0x20($out), $out
-
-       movdqa  0x20(%rsp), @XMM[7]     # next iteration tweak
-       jmp     .Lxts_dec_done
-.align 16
-.Lxts_dec_1:
-       pxor    @XMM[0], @XMM[8]
-       lea     0x10($inp), $inp
-       movdqa  @XMM[8], 0x20(%rbp)
-       lea     0x20(%rbp), $arg1
-       lea     0x20(%rbp), $arg2
-       lea     ($key), $arg3
-       call    asm_AES_decrypt         # doesn't touch %xmm
-       pxor    0x20(%rbp), @XMM[0]     # ^= tweak[]
-       #pxor   @XMM[8], @XMM[0]
-       #lea    0x80(%rsp), %rax        # pass key schedule
-       #mov    %edx, %r10d             # pass rounds
-       #call   _bsaes_decrypt8
-       #pxor   0x00(%rsp), @XMM[0]     # ^= tweak[]
-       movdqu  @XMM[0], 0x00($out)     # write output
-       lea     0x10($out), $out
-
-       movdqa  0x10(%rsp), @XMM[7]     # next iteration tweak
-
-.Lxts_dec_done:
-       and     \$15, %ebx
-       jz      .Lxts_dec_ret
-
-       pxor    $twtmp, $twtmp
-       movdqa  .Lxts_magic(%rip), $twmask
-       pcmpgtd @XMM[7], $twtmp
-       pshufd  \$0x13, $twtmp, $twres
-       movdqa  @XMM[7], @XMM[6]
-       paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
-       pand    $twmask, $twres         # isolate carry and residue
-       movdqu  ($inp), @XMM[0]
-       pxor    $twres, @XMM[7]
-
-       lea     0x20(%rbp), $arg1
-       pxor    @XMM[7], @XMM[0]
-       lea     0x20(%rbp), $arg2
-       movdqa  @XMM[0], 0x20(%rbp)
-       lea     ($key), $arg3
-       call    asm_AES_decrypt         # doesn't touch %xmm
-       pxor    0x20(%rbp), @XMM[7]
-       mov     $out, %rdx
-       movdqu  @XMM[7], ($out)
-
-.Lxts_dec_steal:
-       movzb   16($inp), %eax
-       movzb   (%rdx), %ecx
-       lea     1($inp), $inp
-       mov     %al, (%rdx)
-       mov     %cl, 16(%rdx)
-       lea     1(%rdx), %rdx
-       sub     \$1,%ebx
-       jnz     .Lxts_dec_steal
-
-       movdqu  ($out), @XMM[0]
-       lea     0x20(%rbp), $arg1
-       pxor    @XMM[6], @XMM[0]
-       lea     0x20(%rbp), $arg2
-       movdqa  @XMM[0], 0x20(%rbp)
-       lea     ($key), $arg3
-       call    asm_AES_decrypt         # doesn't touch %xmm
-       pxor    0x20(%rbp), @XMM[6]
-       movdqu  @XMM[6], ($out)
-
-.Lxts_dec_ret:
-       lea     (%rsp), %rax
-       pxor    %xmm0, %xmm0
-.Lxts_dec_bzero:                       # wipe key schedule [if any]
-       movdqa  %xmm0, 0x00(%rax)
-       movdqa  %xmm0, 0x10(%rax)
-       lea     0x20(%rax), %rax
-       cmp     %rax, %rbp
-       ja      .Lxts_dec_bzero
-
-       lea     0x78(%rbp),%rax
-.cfi_def_cfa   %rax,8
-___
-$code.=<<___ if ($win64);
-       movaps  0x40(%rbp), %xmm6
-       movaps  0x50(%rbp), %xmm7
-       movaps  0x60(%rbp), %xmm8
-       movaps  0x70(%rbp), %xmm9
-       movaps  0x80(%rbp), %xmm10
-       movaps  0x90(%rbp), %xmm11
-       movaps  0xa0(%rbp), %xmm12
-       movaps  0xb0(%rbp), %xmm13
-       movaps  0xc0(%rbp), %xmm14
-       movaps  0xd0(%rbp), %xmm15
-       lea     0xa0(%rax), %rax
-.Lxts_dec_tail:
-___
-$code.=<<___;
-       mov     -48(%rax), %r15
-.cfi_restore   %r15
-       mov     -40(%rax), %r14
-.cfi_restore   %r14
-       mov     -32(%rax), %r13
-.cfi_restore   %r13
-       mov     -24(%rax), %r12
-.cfi_restore   %r12
-       mov     -16(%rax), %rbx
-.cfi_restore   %rbx
-       mov     -8(%rax), %rbp
-.cfi_restore   %rbp
-       lea     (%rax), %rsp            # restore %rsp
-.cfi_def_cfa_register  %rsp
-.Lxts_dec_epilogue:
-       ret
-.cfi_endproc
-.size  bsaes_xts_decrypt,.-bsaes_xts_decrypt
-___
-}
-$code.=<<___;
-.type  _bsaes_const,\@object
-.align 64
-_bsaes_const:
-.LM0ISR:       # InvShiftRows constants
-       .quad   0x0a0e0206070b0f03, 0x0004080c0d010509
-.LISRM0:
-       .quad   0x01040b0e0205080f, 0x0306090c00070a0d
-.LISR:
-       .quad   0x0504070602010003, 0x0f0e0d0c080b0a09
-.LBS0:         # bit-slice constants
-       .quad   0x5555555555555555, 0x5555555555555555
-.LBS1:
-       .quad   0x3333333333333333, 0x3333333333333333
-.LBS2:
-       .quad   0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f
-.LSR:          # shiftrows constants
-       .quad   0x0504070600030201, 0x0f0e0d0c0a09080b
-.LSRM0:
-       .quad   0x0304090e00050a0f, 0x01060b0c0207080d
-.LM0SR:
-       .quad   0x0a0e02060f03070b, 0x0004080c05090d01
-.LSWPUP:       # byte-swap upper dword
-       .quad   0x0706050403020100, 0x0c0d0e0f0b0a0908
-.LSWPUPM0SR:
-       .quad   0x0a0d02060c03070b, 0x0004080f05090e01
-.LADD1:                # counter increment constants
-       .quad   0x0000000000000000, 0x0000000100000000
-.LADD2:
-       .quad   0x0000000000000000, 0x0000000200000000
-.LADD3:
-       .quad   0x0000000000000000, 0x0000000300000000
-.LADD4:
-       .quad   0x0000000000000000, 0x0000000400000000
-.LADD5:
-       .quad   0x0000000000000000, 0x0000000500000000
-.LADD6:
-       .quad   0x0000000000000000, 0x0000000600000000
-.LADD7:
-       .quad   0x0000000000000000, 0x0000000700000000
-.LADD8:
-       .quad   0x0000000000000000, 0x0000000800000000
-.Lxts_magic:
-       .long   0x87,0,1,0
-.Lmasks:
-       .quad   0x0101010101010101, 0x0101010101010101
-       .quad   0x0202020202020202, 0x0202020202020202
-       .quad   0x0404040404040404, 0x0404040404040404
-       .quad   0x0808080808080808, 0x0808080808080808
-.LM0:
-       .quad   0x02060a0e03070b0f, 0x0004080c0105090d
-.L63:
-       .quad   0x6363636363636363, 0x6363636363636363
-.asciz "Bit-sliced AES for x86_64/SSSE3, Emilia Käsper, Peter Schwabe, Andy Polyakov"
-.align 64
-.size  _bsaes_const,.-_bsaes_const
-___
-
-# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-#              CONTEXT *context,DISPATCHER_CONTEXT *disp)
-if ($win64) {
-$rec="%rcx";
-$frame="%rdx";
-$context="%r8";
-$disp="%r9";
-
-$code.=<<___;
-.extern        __imp_RtlVirtualUnwind
-.type  se_handler,\@abi-omnipotent
-.align 16
-se_handler:
-       push    %rsi
-       push    %rdi
-       push    %rbx
-       push    %rbp
-       push    %r12
-       push    %r13
-       push    %r14
-       push    %r15
-       pushfq
-       sub     \$64,%rsp
-
-       mov     120($context),%rax      # pull context->Rax
-       mov     248($context),%rbx      # pull context->Rip
-
-       mov     8($disp),%rsi           # disp->ImageBase
-       mov     56($disp),%r11          # disp->HandlerData
-
-       mov     0(%r11),%r10d           # HandlerData[0]
-       lea     (%rsi,%r10),%r10        # prologue label
-       cmp     %r10,%rbx               # context->Rip<=prologue label
-       jbe     .Lin_prologue
-
-       mov     4(%r11),%r10d           # HandlerData[1]
-       lea     (%rsi,%r10),%r10        # epilogue label
-       cmp     %r10,%rbx               # context->Rip>=epilogue label
-       jae     .Lin_prologue
-
-       mov     8(%r11),%r10d           # HandlerData[2]
-       lea     (%rsi,%r10),%r10        # epilogue label
-       cmp     %r10,%rbx               # context->Rip>=tail label
-       jae     .Lin_tail
-
-       mov     160($context),%rax      # pull context->Rbp
-
-       lea     0x40(%rax),%rsi         # %xmm save area
-       lea     512($context),%rdi      # &context.Xmm6
-       mov     \$20,%ecx               # 10*sizeof(%xmm0)/sizeof(%rax)
-       .long   0xa548f3fc              # cld; rep movsq
-       lea     0xa0+0x78(%rax),%rax    # adjust stack pointer
-
-.Lin_tail:
-       mov     -48(%rax),%rbp
-       mov     -40(%rax),%rbx
-       mov     -32(%rax),%r12
-       mov     -24(%rax),%r13
-       mov     -16(%rax),%r14
-       mov     -8(%rax),%r15
-       mov     %rbx,144($context)      # restore context->Rbx
-       mov     %rbp,160($context)      # restore context->Rbp
-       mov     %r12,216($context)      # restore context->R12
-       mov     %r13,224($context)      # restore context->R13
-       mov     %r14,232($context)      # restore context->R14
-       mov     %r15,240($context)      # restore context->R15
-
-.Lin_prologue:
-       mov     %rax,152($context)      # restore context->Rsp
-
-       mov     40($disp),%rdi          # disp->ContextRecord
-       mov     $context,%rsi           # context
-       mov     \$`1232/8`,%ecx         # sizeof(CONTEXT)
-       .long   0xa548f3fc              # cld; rep movsq
-
-       mov     $disp,%rsi
-       xor     %rcx,%rcx               # arg1, UNW_FLAG_NHANDLER
-       mov     8(%rsi),%rdx            # arg2, disp->ImageBase
-       mov     0(%rsi),%r8             # arg3, disp->ControlPc
-       mov     16(%rsi),%r9            # arg4, disp->FunctionEntry
-       mov     40(%rsi),%r10           # disp->ContextRecord
-       lea     56(%rsi),%r11           # &disp->HandlerData
-       lea     24(%rsi),%r12           # &disp->EstablisherFrame
-       mov     %r10,32(%rsp)           # arg5
-       mov     %r11,40(%rsp)           # arg6
-       mov     %r12,48(%rsp)           # arg7
-       mov     %rcx,56(%rsp)           # arg8, (NULL)
-       call    *__imp_RtlVirtualUnwind(%rip)
-
-       mov     \$1,%eax                # ExceptionContinueSearch
-       add     \$64,%rsp
-       popfq
-       pop     %r15
-       pop     %r14
-       pop     %r13
-       pop     %r12
-       pop     %rbp
-       pop     %rbx
-       pop     %rdi
-       pop     %rsi
-       ret
-.size  se_handler,.-se_handler
-
-.section       .pdata
-.align 4
-___
-$code.=<<___ if ($ecb);
-       .rva    .Lecb_enc_prologue
-       .rva    .Lecb_enc_epilogue
-       .rva    .Lecb_enc_info
-
-       .rva    .Lecb_dec_prologue
-       .rva    .Lecb_dec_epilogue
-       .rva    .Lecb_dec_info
-___
-$code.=<<___;
-       .rva    .Lcbc_dec_prologue
-       .rva    .Lcbc_dec_epilogue
-       .rva    .Lcbc_dec_info
-
-       .rva    .Lctr_enc_prologue
-       .rva    .Lctr_enc_epilogue
-       .rva    .Lctr_enc_info
-
-       .rva    .Lxts_enc_prologue
-       .rva    .Lxts_enc_epilogue
-       .rva    .Lxts_enc_info
-
-       .rva    .Lxts_dec_prologue
-       .rva    .Lxts_dec_epilogue
-       .rva    .Lxts_dec_info
-
-.section       .xdata
-.align 8
-___
-$code.=<<___ if ($ecb);
-.Lecb_enc_info:
-       .byte   9,0,0,0
-       .rva    se_handler
-       .rva    .Lecb_enc_body,.Lecb_enc_epilogue       # HandlerData[]
-       .rva    .Lecb_enc_tail
-       .long   0
-.Lecb_dec_info:
-       .byte   9,0,0,0
-       .rva    se_handler
-       .rva    .Lecb_dec_body,.Lecb_dec_epilogue       # HandlerData[]
-       .rva    .Lecb_dec_tail
-       .long   0
-___
-$code.=<<___;
-.Lcbc_dec_info:
-       .byte   9,0,0,0
-       .rva    se_handler
-       .rva    .Lcbc_dec_body,.Lcbc_dec_epilogue       # HandlerData[]
-       .rva    .Lcbc_dec_tail
-       .long   0
-.Lctr_enc_info:
-       .byte   9,0,0,0
-       .rva    se_handler
-       .rva    .Lctr_enc_body,.Lctr_enc_epilogue       # HandlerData[]
-       .rva    .Lctr_enc_tail
-       .long   0
-.Lxts_enc_info:
-       .byte   9,0,0,0
-       .rva    se_handler
-       .rva    .Lxts_enc_body,.Lxts_enc_epilogue       # HandlerData[]
-       .rva    .Lxts_enc_tail
-       .long   0
-.Lxts_dec_info:
-       .byte   9,0,0,0
-       .rva    se_handler
-       .rva    .Lxts_dec_body,.Lxts_dec_epilogue       # HandlerData[]
-       .rva    .Lxts_dec_tail
-       .long   0
-___
-}
-
-$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-
-print $code;
-
-close STDOUT;
index 1babb96..c36dd95 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -67,7 +67,7 @@ static void determine_days(struct tm *tm)
     }
     c = y / 100;
     y %= 100;
-    /* Zeller's congruance */
+    /* Zeller's congruence */
     tm->tm_wday = (d + (13 * m) / 5 + y + y / 4 + c / 4 + 5 * c + 6) % 7;
 }
 
@@ -79,7 +79,11 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d)
     char *a;
     int n, i, i2, l, o, min_l = 11, strict = 0, end = 6, btz = 5, md;
     struct tm tmp;
-
+#if defined(CHARSET_EBCDIC)
+    const char upper_z = 0x5A, num_zero = 0x30, period = 0x2E, minus = 0x2D, plus = 0x2B;
+#else
+    const char upper_z = 'Z', num_zero = '0', period = '.', minus = '-', plus = '+';
+#endif
     /*
      * ASN1_STRING_FLAG_X509_TIME is used to enforce RFC 5280
      * time string format, in which:
@@ -120,20 +124,20 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d)
     if (l < min_l)
         goto err;
     for (i = 0; i < end; i++) {
-        if (!strict && (i == btz) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+        if (!strict && (i == btz) && ((a[o] == upper_z) || (a[o] == plus) || (a[o] == minus))) {
             i++;
             break;
         }
-        if (!ossl_isdigit(a[o]))
+        if (!ascii_isdigit(a[o]))
             goto err;
-        n = a[o] - '0';
+        n = a[o] - num_zero;
         /* incomplete 2-digital number */
         if (++o == l)
             goto err;
 
-        if (!ossl_isdigit(a[o]))
+        if (!ascii_isdigit(a[o]))
             goto err;
-        n = (n * 10) + a[o] - '0';
+        n = (n * 10) + a[o] - num_zero;
         /* no more bytes to read, but we haven't seen time-zone yet */
         if (++o == l)
             goto err;
@@ -185,14 +189,14 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d)
      * Optional fractional seconds: decimal point followed by one or more
      * digits.
      */
-    if (d->type == V_ASN1_GENERALIZEDTIME && a[o] == '.') {
+    if (d->type == V_ASN1_GENERALIZEDTIME && a[o] == period) {
         if (strict)
             /* RFC 5280 forbids fractional seconds */
             goto err;
         if (++o == l)
             goto err;
         i = o;
-        while ((o < l) && ossl_isdigit(a[o]))
+        while ((o < l) && ascii_isdigit(a[o]))
             o++;
         /* Must have at least one digit after decimal point */
         if (i == o)
@@ -207,10 +211,10 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d)
      * 'o' can point to '\0' is either the subsequent if or the first
      * else if is true.
      */
-    if (a[o] == 'Z') {
+    if (a[o] == upper_z) {
         o++;
-    } else if (!strict && ((a[o] == '+') || (a[o] == '-'))) {
-        int offsign = a[o] == '-' ? 1 : -1;
+    } else if (!strict && ((a[o] == plus) || (a[o] == minus))) {
+        int offsign = a[o] == minus ? 1 : -1;
         int offset = 0;
 
         o++;
@@ -223,13 +227,13 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d)
         if (o + 4 != l)
             goto err;
         for (i = end; i < end + 2; i++) {
-            if (!ossl_isdigit(a[o]))
+            if (!ascii_isdigit(a[o]))
                 goto err;
-            n = a[o] - '0';
+            n = a[o] - num_zero;
             o++;
-            if (!ossl_isdigit(a[o]))
+            if (!ascii_isdigit(a[o]))
                 goto err;
-            n = (n * 10) + a[o] - '0';
+            n = (n * 10) + a[o] - num_zero;
             i2 = (d->type == V_ASN1_UTCTIME) ? i + 1 : i;
             if ((n < min[i2]) || (n > max[i2]))
                 goto err;
@@ -300,7 +304,7 @@ ASN1_TIME *asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type)
                                     ts->tm_mday, ts->tm_hour, ts->tm_min,
                                     ts->tm_sec);
 
-#ifdef CHARSET_EBCDIC_not
+#ifdef CHARSET_EBCDIC
     ebcdic2ascii(tmps->data, tmps->data, tmps->length);
 #endif
     return tmps;
@@ -467,6 +471,7 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
     char *v;
     int gmt = 0, l;
     struct tm stm;
+    const char upper_z = 0x5A, period = 0x2E;
 
     if (!asn1_time_to_tm(&stm, tm)) {
         /* asn1_time_to_tm will check the time type */
@@ -475,7 +480,7 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
 
     l = tm->length;
     v = (char *)tm->data;
-    if (v[l - 1] == 'Z')
+    if (v[l - 1] == upper_z)
         gmt = 1;
 
     if (tm->type == V_ASN1_GENERALIZEDTIME) {
@@ -486,10 +491,10 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
          * Try to parse fractional seconds. '14' is the place of
          * 'fraction point' in a GeneralizedTime string.
          */
-        if (tm->length > 15 && v[14] == '.') {
+        if (tm->length > 15 && v[14] == period) {
             f = &v[14];
             f_len = 1;
-            while (14 + f_len < l && ossl_isdigit(f[f_len]))
+            while (14 + f_len < l && ascii_isdigit(f[f_len]))
                 ++f_len;
         }
 
index 0c7aebe..732328e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -15,7 +15,9 @@
 
 int ASN1_TYPE_get(const ASN1_TYPE *a)
 {
-    if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
+    if (a->type == V_ASN1_BOOLEAN
+            || a->type == V_ASN1_NULL
+            || a->value.ptr != NULL)
         return a->type;
     else
         return 0;
@@ -23,7 +25,9 @@ int ASN1_TYPE_get(const ASN1_TYPE *a)
 
 void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
 {
-    if (a->value.ptr != NULL) {
+    if (a->type != V_ASN1_BOOLEAN
+            && a->type != V_ASN1_NULL
+            && a->value.ptr != NULL) {
         ASN1_TYPE **tmp_a = &a;
         asn1_primitive_free((ASN1_VALUE **)tmp_a, NULL, 0);
     }
index da57e77..6c93ea7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -130,9 +130,20 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
 static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
                          int utype, char *free_cont, const ASN1_ITEM *it)
 {
-    if (!*pval)
-        bn_secure_new(pval, it);
-    return bn_c2i(pval, cont, len, utype, free_cont, it);
+    int ret;
+    BIGNUM *bn;
+
+    if (!*pval && !bn_secure_new(pval, it))
+        return 0;
+
+    ret = bn_c2i(pval, cont, len, utype, free_cont, it);
+    if (!ret)
+        return 0;
+
+    /* Set constant-time flag for all secure BIGNUMS */
+    bn = (BIGNUM *)*pval;
+    BN_set_flags(bn, BN_FLG_CONSTTIME);
+    return ret;
 }
 
 static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
index f295b76..dd5008e 100644 (file)
@@ -675,7 +675,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
 
     if (1) {
 #ifdef AI_PASSIVE
-        int gai_ret = 0;
+        int gai_ret = 0, old_ret = 0;
         struct addrinfo hints;
 
         memset(&hints, 0, sizeof(hints));
@@ -683,12 +683,12 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
         hints.ai_family = family;
         hints.ai_socktype = socktype;
         hints.ai_protocol = protocol;
-#ifdef AI_ADDRCONFIG
-#ifdef AF_UNSPEC
+# ifdef AI_ADDRCONFIG
+#  ifdef AF_UNSPEC
         if (family == AF_UNSPEC)
-#endif
+#  endif
             hints.ai_flags |= AI_ADDRCONFIG;
-#endif
+# endif
 
         if (lookup_type == BIO_LOOKUP_SERVER)
             hints.ai_flags |= AI_PASSIVE;
@@ -696,6 +696,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
         /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
          * macro magic in bio_lcl.h
          */
+      retry:
         switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
 # ifdef EAI_SYSTEM
         case EAI_SYSTEM:
@@ -703,12 +704,25 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
             BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB);
             break;
 # endif
+# ifdef EAI_MEMORY
+        case EAI_MEMORY:
+            BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
+            break;
+# endif
         case 0:
             ret = 1;             /* Success */
             break;
         default:
+# if defined(AI_ADDRCONFIG) && defined(AI_NUMERICHOST)
+            if (hints.ai_flags & AI_ADDRCONFIG) {
+                hints.ai_flags &= ~AI_ADDRCONFIG;
+                hints.ai_flags |= AI_NUMERICHOST;
+                old_ret = gai_ret;
+                goto retry;
+            }
+# endif
             BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB);
-            ERR_add_error_data(1, gai_strerror(gai_ret));
+            ERR_add_error_data(1, gai_strerror(old_ret ? old_ret : gai_ret));
             break;
         }
     } else {
index d5fe5bb..5518216 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -784,7 +784,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
      * reasons. When BIO_CTRL_DGRAM_SET_PEEK_MODE was first defined its value
      * was incorrectly clashing with BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE. The
      * value has been updated to a non-clashing value. However to preserve
-     * binary compatiblity we now respond to both the old value and the new one
+     * binary compatibility we now respond to both the old value and the new one
      */
     case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
     case BIO_CTRL_DGRAM_SET_PEEK_MODE:
index 0573447..a210205 100644 (file)
@@ -7,10 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
-#ifndef HEADER_BSS_FILE_C
-# define HEADER_BSS_FILE_C
-
-# if defined(__linux) || defined(__sun) || defined(__hpux)
+#if defined(__linux) || defined(__sun) || defined(__hpux)
 /*
  * Following definition aliases fopen to fopen64 on above mentioned
  * platforms. This makes it possible to open and sequentially access files
  * of 32-bit platforms which allow for sequential access of large files
  * without extra "magic" comprise *BSD, Darwin, IRIX...
  */
-#  ifndef _FILE_OFFSET_BITS
-#   define _FILE_OFFSET_BITS 64
-#  endif
+# ifndef _FILE_OFFSET_BITS
+#  define _FILE_OFFSET_BITS 64
 # endif
+#endif
 
-# include <stdio.h>
-# include <errno.h>
-# include "bio_lcl.h"
-# include <openssl/err.h>
+#include <stdio.h>
+#include <errno.h>
+#include "bio_lcl.h"
+#include <openssl/err.h>
 
-# if !defined(OPENSSL_NO_STDIO)
+#if !defined(OPENSSL_NO_STDIO)
 
 static int file_write(BIO *h, const char *buf, int num);
 static int file_read(BIO *h, char *buf, int size);
@@ -72,9 +69,9 @@ BIO *BIO_new_file(const char *filename, const char *mode)
         SYSerr(SYS_F_FOPEN, get_last_sys_error());
         ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
         if (errno == ENOENT
-# ifdef ENXIO
+#ifdef ENXIO
             || errno == ENXIO
-# endif
+#endif
             )
             BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
         else
@@ -212,33 +209,33 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
         b->shutdown = (int)num & BIO_CLOSE;
         b->ptr = ptr;
         b->init = 1;
-#  if BIO_FLAGS_UPLINK!=0
-#   if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
-#    define _IOB_ENTRIES 20
-#   endif
+# if BIO_FLAGS_UPLINK!=0
+#  if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
+#   define _IOB_ENTRIES 20
+#  endif
         /* Safety net to catch purely internal BIO_set_fp calls */
-#   if defined(_MSC_VER) && _MSC_VER>=1900
+#  if defined(_MSC_VER) && _MSC_VER>=1900
         if (ptr == stdin || ptr == stdout || ptr == stderr)
             BIO_clear_flags(b, BIO_FLAGS_UPLINK);
-#   elif defined(_IOB_ENTRIES)
+#  elif defined(_IOB_ENTRIES)
         if ((size_t)ptr >= (size_t)stdin &&
             (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
             BIO_clear_flags(b, BIO_FLAGS_UPLINK);
-#   endif
 #  endif
-#  ifdef UP_fsetmod
+# endif
+# ifdef UP_fsetmod
         if (b->flags & BIO_FLAGS_UPLINK)
             UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b'));
         else
-#  endif
+# endif
         {
-#  if defined(OPENSSL_SYS_WINDOWS)
+# if defined(OPENSSL_SYS_WINDOWS)
             int fd = _fileno((FILE *)ptr);
             if (num & BIO_FP_TEXT)
                 _setmode(fd, _O_TEXT);
             else
                 _setmode(fd, _O_BINARY);
-#  elif defined(OPENSSL_SYS_MSDOS)
+# elif defined(OPENSSL_SYS_MSDOS)
             int fd = fileno((FILE *)ptr);
             /* Set correct text/binary mode */
             if (num & BIO_FP_TEXT)
@@ -251,11 +248,11 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
                 } else
                     _setmode(fd, _O_BINARY);
             }
-#  elif defined(OPENSSL_SYS_WIN32_CYGWIN)
+# elif defined(OPENSSL_SYS_WIN32_CYGWIN)
             int fd = fileno((FILE *)ptr);
             if (!(num & BIO_FP_TEXT))
                 setmode(fd, O_BINARY);
-#  endif
+# endif
         }
         break;
     case BIO_C_SET_FILENAME:
@@ -277,15 +274,15 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
             ret = 0;
             break;
         }
-#  if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS)
+# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS)
         if (!(num & BIO_FP_TEXT))
             OPENSSL_strlcat(p, "b", sizeof(p));
         else
             OPENSSL_strlcat(p, "t", sizeof(p));
-#  elif defined(OPENSSL_SYS_WIN32_CYGWIN)
+# elif defined(OPENSSL_SYS_WIN32_CYGWIN)
         if (!(num & BIO_FP_TEXT))
             OPENSSL_strlcat(p, "b", sizeof(p));
-#  endif
+# endif
         fp = openssl_fopen(ptr, p);
         if (fp == NULL) {
             SYSerr(SYS_F_FOPEN, get_last_sys_error());
@@ -422,6 +419,4 @@ BIO *BIO_new_file(const char *filename, const char *mode)
     return NULL;
 }
 
-# endif                         /* OPENSSL_NO_STDIO */
-
-#endif                          /* HEADER_BSS_FILE_C */
+#endif                         /* OPENSSL_NO_STDIO */
index 8c621d6..2d536e9 100644 (file)
@@ -259,9 +259,7 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
         bm = bbm->buf;
         if (bm->data != NULL) {
             if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) {
-                if (b->flags & BIO_FLAGS_NONCLEAR_RST) {
-                    bm->length = bm->max;
-                } else {
+                if (!(b->flags & BIO_FLAGS_NONCLEAR_RST)) {
                     memset(bm->data, 0, bm->max);
                     bm->length = 0;
                 }
index 38b796e..a205189 100644 (file)
@@ -801,7 +801,7 @@ $code.=<<___;
 #if 0
 /*
  * The bn_div_3_words entry point is re-used for constant-time interface.
- * Implementation is retained as hystorical reference.
+ * Implementation is retained as historical reference.
  */
 .align 5
 .globl bn_div_3_words
index 3a6fa0a..7fc0132 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -258,7 +258,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
  *
  *     - availability of constant-time bn_div_3_words;
  *     - dividend is at least as "wide" as divisor, limb-wise, zero-padded
- *       if so requied, which shouldn't be a privacy problem, because
+ *       if so required, which shouldn't be a privacy problem, because
  *       divisor's length is considered public;
  */
 int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
index 8a36db2..7f823a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -295,7 +295,7 @@ struct bn_gencb_st {
                  (b) >  23 ? 3 : 1)
 
 /*
- * BN_mod_exp_mont_conttime is based on the assumption that the L1 data cache
+ * BN_mod_exp_mont_consttime is based on the assumption that the L1 data cache
  * line width of the target processor is at least the following value.
  */
 # define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH      ( 64 )
index f93bbcf..254069f 100644 (file)
@@ -132,20 +132,66 @@ int BN_num_bits_word(BN_ULONG l)
     return bits;
 }
 
+/*
+ * This function still leaks `a->dmax`: it's caller's responsibility to
+ * expand the input `a` in advance to a public length.
+ */
+static ossl_inline
+int bn_num_bits_consttime(const BIGNUM *a)
+{
+    int j, ret;
+    unsigned int mask, past_i;
+    int i = a->top - 1;
+    bn_check_top(a);
+
+    for (j = 0, past_i = 0, ret = 0; j < a->dmax; j++) {
+        mask = constant_time_eq_int(i, j); /* 0xff..ff if i==j, 0x0 otherwise */
+
+        ret += BN_BITS2 & (~mask & ~past_i);
+        ret += BN_num_bits_word(a->d[j]) & mask;
+
+        past_i |= mask; /* past_i will become 0xff..ff after i==j */
+    }
+
+    /*
+     * if BN_is_zero(a) => i is -1 and ret contains garbage, so we mask the
+     * final result.
+     */
+    mask = ~(constant_time_eq_int(i, ((int)-1)));
+
+    return ret & mask;
+}
+
 int BN_num_bits(const BIGNUM *a)
 {
     int i = a->top - 1;
     bn_check_top(a);
 
+    if (a->flags & BN_FLG_CONSTTIME) {
+        /*
+         * We assume that BIGNUMs flagged as CONSTTIME have also been expanded
+         * so that a->dmax is not leaking secret information.
+         *
+         * In other words, it's the caller's responsibility to ensure `a` has
+         * been preallocated in advance to a public length if we hit this
+         * branch.
+         *
+         */
+        return bn_num_bits_consttime(a);
+    }
+
     if (BN_is_zero(a))
         return 0;
+
     return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
 }
 
-static void bn_free_d(BIGNUM *a)
+static void bn_free_d(BIGNUM *a, int clear)
 {
     if (BN_get_flags(a, BN_FLG_SECURE))
-        OPENSSL_secure_free(a->d);
+        OPENSSL_secure_clear_free(a->d, a->dmax * sizeof(a->d[0]));
+    else if (clear != 0)
+        OPENSSL_clear_free(a->d, a->dmax * sizeof(a->d[0]));
     else
         OPENSSL_free(a->d);
 }
@@ -155,10 +201,8 @@ void BN_clear_free(BIGNUM *a)
 {
     if (a == NULL)
         return;
-    if (a->d != NULL && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {
-        OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
-        bn_free_d(a);
-    }
+    if (a->d != NULL && !BN_get_flags(a, BN_FLG_STATIC_DATA))
+        bn_free_d(a, 1);
     if (BN_get_flags(a, BN_FLG_MALLOCED)) {
         OPENSSL_cleanse(a, sizeof(*a));
         OPENSSL_free(a);
@@ -170,7 +214,7 @@ void BN_free(BIGNUM *a)
     if (a == NULL)
         return;
     if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
-        bn_free_d(a);
+        bn_free_d(a, 0);
     if (a->flags & BN_FLG_MALLOCED)
         OPENSSL_free(a);
 }
@@ -248,10 +292,8 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
         BN_ULONG *a = bn_expand_internal(b, words);
         if (!a)
             return NULL;
-        if (b->d) {
-            OPENSSL_cleanse(b->d, b->dmax * sizeof(b->d[0]));
-            bn_free_d(b);
-        }
+        if (b->d != NULL)
+            bn_free_d(b, 1);
         b->d = a;
         b->dmax = words;
     }
@@ -416,8 +458,11 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
     return ret;
 }
 
+typedef enum {big, little} endianess_t;
+
 /* ignore negative */
-static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
+static
+int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endianess)
 {
     int n;
     size_t i, lasti, j, atop, mask;
@@ -449,10 +494,17 @@ static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
 
     lasti = atop - 1;
     atop = a->top * BN_BYTES;
-    for (i = 0, j = 0, to += tolen; j < (size_t)tolen; j++) {
+    if (endianess == big)
+        to += tolen; /* start from the end of the buffer */
+    for (i = 0, j = 0; j < (size_t)tolen; j++) {
+        unsigned char val;
         l = a->d[i / BN_BYTES];
         mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
-        *--to = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
+        val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
+        if (endianess == big)
+            *--to = val;
+        else
+            *to++ = val;
         i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
     }
 
@@ -463,12 +515,12 @@ int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
 {
     if (tolen < 0)
         return -1;
-    return bn2binpad(a, to, tolen);
+    return bn2binpad(a, to, tolen, big);
 }
 
 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
 {
-    return bn2binpad(a, to, -1);
+    return bn2binpad(a, to, -1, big);
 }
 
 BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
@@ -520,22 +572,9 @@ BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
 
 int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
 {
-    int i;
-    BN_ULONG l;
-    bn_check_top(a);
-    i = BN_num_bytes(a);
-    if (tolen < i)
+    if (tolen < 0)
         return -1;
-    /* Add trailing zeroes if necessary */
-    if (tolen > i)
-        memset(to + i, 0, tolen - i);
-    to += i;
-    while (i--) {
-        l = a->d[i / BN_BYTES];
-        to--;
-        *to = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
-    }
-    return tolen;
+    return bn2binpad(a, to, tolen, little);
 }
 
 int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
index 4bbd7c8..19b081f 100644 (file)
@@ -63,8 +63,12 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
         /* There are no prime numbers this small. */
         BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
         return 0;
-    } else if (bits == 2 && safe) {
-        /* The smallest safe prime (7) is three bits. */
+    } else if (add == NULL && safe && bits < 6 && bits != 3) {
+        /*
+         * The smallest safe prime (7) is three bits.
+         * But the following two safe primes with less than 6 bits (11, 23)
+         * are unreachable for BN_rand with BN_RAND_TOP_TWO.
+         */
         BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
         return 0;
     }
index c0d1a32..051f29e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -225,8 +225,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
         goto err;
 
     /* We copy |priv| into a local buffer to avoid exposing its length. */
-    todo = sizeof(priv->d[0]) * priv->top;
-    if (todo > sizeof(private_bytes)) {
+    if (BN_bn2binpad(priv, private_bytes, sizeof(private_bytes)) < 0) {
         /*
          * No reasonable DSA or ECDSA key should have a private key this
          * large and we don't handle this case in order to avoid leaking the
@@ -235,8 +234,6 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
         BNerr(BN_F_BN_GENERATE_DSA_NONCE, BN_R_PRIVATE_KEY_TOO_LARGE);
         goto err;
     }
-    memcpy(private_bytes, priv->d, todo);
-    memset(private_bytes + todo, 0, sizeof(private_bytes) - todo);
 
     for (done = 0; done < num_k_bytes;) {
         if (RAND_priv_bytes(random_bytes, sizeof(random_bytes)) != 1)
index b97d8ca..c3e66b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -125,7 +125,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
          *         = a.
          *
          * (This is due to A.O.L. Atkin,
-         * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
+         * Subject: Square Roots and Cognate Matters modulo p=8n+5.
+         * URL: https://listserv.nodak.edu/cgi-bin/wa.exe?A2=ind9211&L=NMBRTHRY&P=4026
          * November 1992.)
          */
 
index 664e649..0566019 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #include <openssl/err.h>
 #include <openssl/cms.h>
 #include "cms_lcl.h"
+#include "internal/nelem.h"
+
+/*-
+ * Attribute flags.
+ * CMS attribute restrictions are discussed in
+ *  - RFC 5652 Section 11.
+ * ESS attribute restrictions are discussed in
+ *  - RFC 2634 Section 1.3.4  AND
+ *  - RFC 5035 Section 5.4
+ */
+/* This is a signed attribute */
+#define CMS_ATTR_F_SIGNED         0x01
+/* This is an unsigned attribute */
+#define CMS_ATTR_F_UNSIGNED       0x02
+/* Must be present if there are any other attributes of the same type */
+#define CMS_ATTR_F_REQUIRED_COND  0x10
+/* There can only be one instance of this attribute */
+#define CMS_ATTR_F_ONLY_ONE       0x20
+/* The Attribute's value must have exactly one entry */
+#define CMS_ATTR_F_ONE_ATTR_VALUE 0x40
+
+/* Attributes rules for different attributes */
+static const struct {
+    int nid;   /* The attribute id */
+    int flags;
+} cms_attribute_properties[] = {
+    /* See RFC Section 11 */
+    { NID_pkcs9_contentType, CMS_ATTR_F_SIGNED
+                             | CMS_ATTR_F_ONLY_ONE
+                             | CMS_ATTR_F_ONE_ATTR_VALUE
+                             | CMS_ATTR_F_REQUIRED_COND },
+    { NID_pkcs9_messageDigest, CMS_ATTR_F_SIGNED
+                               | CMS_ATTR_F_ONLY_ONE
+                               | CMS_ATTR_F_ONE_ATTR_VALUE
+                               | CMS_ATTR_F_REQUIRED_COND },
+    { NID_pkcs9_signingTime, CMS_ATTR_F_SIGNED
+                             | CMS_ATTR_F_ONLY_ONE
+                             | CMS_ATTR_F_ONE_ATTR_VALUE },
+    { NID_pkcs9_countersignature, CMS_ATTR_F_UNSIGNED },
+    /* ESS */
+    { NID_id_smime_aa_signingCertificate, CMS_ATTR_F_SIGNED
+                                          | CMS_ATTR_F_ONLY_ONE
+                                          | CMS_ATTR_F_ONE_ATTR_VALUE },
+    { NID_id_smime_aa_signingCertificateV2, CMS_ATTR_F_SIGNED
+                                            | CMS_ATTR_F_ONLY_ONE
+                                            | CMS_ATTR_F_ONE_ATTR_VALUE },
+    { NID_id_smime_aa_receiptRequest, CMS_ATTR_F_SIGNED
+                                      | CMS_ATTR_F_ONLY_ONE
+                                      | CMS_ATTR_F_ONE_ATTR_VALUE }
+};
 
 /* CMS SignedData Attribute utilities */
 
@@ -149,4 +199,86 @@ void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
     return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
 }
 
-/* Specific attribute cases */
+/*
+ * Retrieve an attribute by nid from a stack of attributes starting at index
+ * *lastpos + 1.
+ * Returns the attribute or NULL if there is no attribute.
+ * If an attribute was found *lastpos returns the index of the found attribute.
+ */
+static X509_ATTRIBUTE *cms_attrib_get(int nid,
+                                      const STACK_OF(X509_ATTRIBUTE) *attrs,
+                                      int *lastpos)
+{
+    X509_ATTRIBUTE *at;
+    int loc;
+
+    loc = X509at_get_attr_by_NID(attrs, nid, *lastpos);
+    if (loc < 0)
+        return NULL;
+
+    at = X509at_get_attr(attrs, loc);
+    *lastpos = loc;
+    return at;
+}
+
+static int cms_check_attribute(int nid, int flags, int type,
+                               const STACK_OF(X509_ATTRIBUTE) *attrs,
+                               int have_attrs)
+{
+    int lastpos = -1;
+    X509_ATTRIBUTE *at = cms_attrib_get(nid, attrs, &lastpos);
+
+    if (at != NULL) {
+        int count = X509_ATTRIBUTE_count(at);
+
+        /* Is this attribute allowed? */
+        if (((flags & type) == 0)
+            /* check if multiple attributes of the same type are allowed */
+            || (((flags & CMS_ATTR_F_ONLY_ONE) != 0)
+                && cms_attrib_get(nid, attrs, &lastpos) != NULL)
+            /* Check if attribute should have exactly one value in its set */
+            || (((flags & CMS_ATTR_F_ONE_ATTR_VALUE) != 0)
+                && count != 1)
+            /* There should be at least one value */
+            || count == 0)
+        return 0;
+    } else {
+        /* fail if a required attribute is missing */
+        if (have_attrs
+            && ((flags & CMS_ATTR_F_REQUIRED_COND) != 0)
+            && (flags & type) != 0)
+            return 0;
+    }
+    return 1;
+}
+
+/*
+ * Check that the signerinfo attributes obey the attribute rules which includes
+ * the following checks
+ * - If any signed attributes exist then there must be a Content Type
+ * and Message Digest attribute in the signed attributes.
+ * - The countersignature attribute is an optional unsigned attribute only.
+ * - Content Type, Message Digest, and Signing time attributes are signed
+ *     attributes. Only one instance of each is allowed, with each of these
+ *     attributes containing a single attribute value in its set.
+ */
+int CMS_si_check_attributes(const CMS_SignerInfo *si)
+{
+    int i;
+    int have_signed_attrs = (CMS_signed_get_attr_count(si) > 0);
+    int have_unsigned_attrs = (CMS_unsigned_get_attr_count(si) > 0);
+
+    for (i = 0; i < (int)OSSL_NELEM(cms_attribute_properties); ++i) {
+        int nid = cms_attribute_properties[i].nid;
+        int flags = cms_attribute_properties[i].flags;
+
+        if (!cms_check_attribute(nid, flags, CMS_ATTR_F_SIGNED,
+                                 si->signedAttrs, have_signed_attrs)
+            || !cms_check_attribute(nid, flags, CMS_ATTR_F_UNSIGNED,
+                                    si->unsignedAttrs, have_unsigned_attrs)) {
+            CMSerr(CMS_F_CMS_SI_CHECK_ATTRIBUTES, CMS_R_ATTRIBUTE_ERROR);
+            return 0;
+        }
+    }
+    return 1;
+}
index bb95af7..26fb81f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -363,6 +363,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
     unsigned char *ek = NULL;
     size_t eklen;
     int ret = 0;
+    size_t fixlen = 0;
     CMS_EncryptedContentInfo *ec;
     ec = cms->d.envelopedData->encryptedContentInfo;
 
@@ -371,6 +372,19 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
         return 0;
     }
 
+    if (cms->d.envelopedData->encryptedContentInfo->havenocert
+            && !cms->d.envelopedData->encryptedContentInfo->debug) {
+        X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
+        const EVP_CIPHER *ciph = EVP_get_cipherbyobj(calg->algorithm);
+
+        if (ciph == NULL) {
+            CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER);
+            return 0;
+        }
+
+        fixlen = EVP_CIPHER_key_length(ciph);
+    }
+
     ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
     if (ktri->pctx == NULL)
         return 0;
@@ -401,7 +415,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
 
     if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
                          ktri->encryptedKey->data,
-                         ktri->encryptedKey->length) <= 0) {
+                         ktri->encryptedKey->length) <= 0
+            || eklen == 0
+            || (fixlen != 0 && eklen != fixlen)) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
         goto err;
     }
index 4432b47..a211f49 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -146,6 +146,8 @@ static const ERR_STRING_DATA CMS_str_functs[] = {
     {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 0),
      "CMS_SignerInfo_verify_content"},
     {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGN_RECEIPT, 0), "CMS_sign_receipt"},
+    {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SI_CHECK_ATTRIBUTES, 0),
+     "CMS_si_check_attributes"},
     {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_STREAM, 0), "CMS_stream"},
     {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_UNCOMPRESS, 0), "CMS_uncompress"},
     {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_VERIFY, 0), "CMS_verify"},
@@ -155,6 +157,7 @@ static const ERR_STRING_DATA CMS_str_functs[] = {
 
 static const ERR_STRING_DATA CMS_str_reasons[] = {
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ADD_SIGNER_ERROR), "add signer error"},
+    {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ATTRIBUTE_ERROR), "attribute error"},
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_ALREADY_PRESENT),
     "certificate already present"},
     {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_HAS_NO_KEYID),
index 916fcbf..68aa012 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -125,6 +125,8 @@ struct CMS_EncryptedContentInfo_st {
     size_t keylen;
     /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
     int debug;
+    /* Set to 1 if we have no cert and need extra safety measures for MMA */
+    int havenocert;
 };
 
 struct CMS_RecipientInfo_st {
@@ -317,8 +319,6 @@ struct CMS_OtherKeyAttribute_st {
 
 /* ESS structures */
 
-# ifdef HEADER_X509V3_H
-
 struct CMS_ReceiptRequest_st {
     ASN1_OCTET_STRING *signedContentIdentifier;
     CMS_ReceiptsFrom *receiptsFrom;
@@ -332,7 +332,6 @@ struct CMS_ReceiptsFrom_st {
         STACK_OF(GENERAL_NAMES) *receiptList;
     } d;
 };
-# endif
 
 struct CMS_Receipt_st {
     int32_t version;
@@ -416,6 +415,8 @@ int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
 /* PWRI routines */
 int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
                                  int en_de);
+/* SignerInfo routines */
+int CMS_si_check_attributes(const CMS_SignerInfo *si);
 
 DECLARE_ASN1_ITEM(CMS_CertificateChoices)
 DECLARE_ASN1_ITEM(CMS_DigestedData)
index ff2d540..3841513 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -109,6 +109,27 @@ static void cms_sd_set_version(CMS_SignedData *sd)
 
 }
 
+/*
+ * RFC 5652 Section 11.1 Content Type
+ * The content-type attribute within signed-data MUST
+ *   1) be present if there are signed attributes
+ *   2) match the content type in the signed-data,
+ *   3) be a signed attribute.
+ *   4) not have more than one copy of the attribute.
+ *
+ * Note that since the CMS_SignerInfo_sign() always adds the "signing time"
+ * attribute, the content type attribute MUST be added also.
+ * Assumptions: This assumes that the attribute does not already exist.
+ */
+static int cms_set_si_contentType_attr(CMS_ContentInfo *cms, CMS_SignerInfo *si)
+{
+    ASN1_OBJECT *ctype = cms->d.signedData->encapContentInfo->eContentType;
+
+    /* Add the contentType attribute */
+    return CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
+                                       V_ASN1_OBJECT, ctype, -1) > 0;
+}
+
 /* Copy an existing messageDigest value */
 
 static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
@@ -328,6 +349,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
         if (flags & CMS_REUSE_DIGEST) {
             if (!cms_copy_messageDigest(cms, si))
                 goto err;
+            if (!cms_set_si_contentType_attr(cms, si))
+                goto err;
             if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
                 !CMS_SignerInfo_sign(si))
                 goto err;
@@ -558,8 +581,6 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
      */
 
     if (CMS_signed_get_attr_count(si) >= 0) {
-        ASN1_OBJECT *ctype =
-            cms->d.signedData->encapContentInfo->eContentType;
         unsigned char md[EVP_MAX_MD_SIZE];
         unsigned int mdlen;
         if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
@@ -568,9 +589,9 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
                                          V_ASN1_OCTET_STRING, md, mdlen))
             goto err;
         /* Copy content type across */
-        if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
-                                        V_ASN1_OBJECT, ctype, -1) <= 0)
+        if (!cms_set_si_contentType_attr(cms, si))
             goto err;
+
         if (!CMS_SignerInfo_sign(si))
             goto err;
     } else if (si->pctx) {
@@ -650,6 +671,9 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
             goto err;
     }
 
+    if (!CMS_si_check_attributes(si))
+        goto err;
+
     if (si->pctx)
         pctx = si->pctx;
     else {
@@ -696,7 +720,6 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
     OPENSSL_free(abuf);
     EVP_MD_CTX_reset(mctx);
     return 0;
-
 }
 
 int CMS_SignerInfo_verify(CMS_SignerInfo *si)
@@ -711,6 +734,9 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
         return -1;
     }
 
+    if (!CMS_si_check_attributes(si))
+        return -1;
+
     md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
     if (md == NULL)
         return -1;
index 5dcf803..1081563 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -743,6 +743,10 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
         cms->d.envelopedData->encryptedContentInfo->debug = 1;
     else
         cms->d.envelopedData->encryptedContentInfo->debug = 0;
+    if (!cert)
+        cms->d.envelopedData->encryptedContentInfo->havenocert = 1;
+    else
+        cms->d.envelopedData->encryptedContentInfo->havenocert = 0;
     if (!pk && !cert && !dcont && !out)
         return 1;
     if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
index 3805c42..82105de 100644 (file)
@@ -42,7 +42,7 @@ void OPENSSL_config(const char *appname)
 
 int openssl_config_int(const OPENSSL_INIT_SETTINGS *settings)
 {
-    int ret;
+    int ret = 0;
     const char *filename;
     const char *appname;
     unsigned long flags;
index 813be25..e05f84c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -272,3 +272,9 @@ int ossl_toupper(int c)
 {
     return ossl_islower(c) ? c ^ case_change : c;
 }
+
+int ascii_isdigit(const char inchar) {
+    if (inchar > 0x2F && inchar < 0x3A)
+        return 1;
+    return 0;
+}
index c7e1dbf..d13d820 100644 (file)
@@ -24,7 +24,8 @@ int DH_check_params_ex(const DH *dh)
 {
     int errflags = 0;
 
-    (void)DH_check_params(dh, &errflags);
+    if (!DH_check_params(dh, &errflags))
+        return 0;
 
     if ((errflags & DH_CHECK_P_NOT_PRIME) != 0)
         DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_CHECK_P_NOT_PRIME);
@@ -67,18 +68,14 @@ int DH_check_params(const DH *dh, int *ret)
 
 /*-
  * Check that p is a safe prime and
- * if g is 2, 3 or 5, check that it is a suitable generator
- * where
- * for 2, p mod 24 == 11
- * for 3, p mod 12 == 5
- * for 5, p mod 10 == 3 or 7
- * should hold.
+ * g is a suitable generator.
  */
 int DH_check_ex(const DH *dh)
 {
     int errflags = 0;
 
-    (void)DH_check(dh, &errflags);
+    if (!DH_check(dh, &errflags))
+        return 0;
 
     if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0)
         DHerr(DH_F_DH_CHECK_EX, DH_R_NOT_SUITABLE_GENERATOR);
@@ -102,10 +99,11 @@ int DH_check(const DH *dh, int *ret)
 {
     int ok = 0, r;
     BN_CTX *ctx = NULL;
-    BN_ULONG l;
     BIGNUM *t1 = NULL, *t2 = NULL;
 
-    *ret = 0;
+    if (!DH_check_params(dh, ret))
+        return 0;
+
     ctx = BN_CTX_new();
     if (ctx == NULL)
         goto err;
@@ -139,21 +137,7 @@ int DH_check(const DH *dh, int *ret)
             *ret |= DH_CHECK_INVALID_Q_VALUE;
         if (dh->j && BN_cmp(dh->j, t1))
             *ret |= DH_CHECK_INVALID_J_VALUE;
-
-    } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
-        l = BN_mod_word(dh->p, 24);
-        if (l == (BN_ULONG)-1)
-            goto err;
-        if (l != 11)
-            *ret |= DH_NOT_SUITABLE_GENERATOR;
-    } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
-        l = BN_mod_word(dh->p, 10);
-        if (l == (BN_ULONG)-1)
-            goto err;
-        if ((l != 3) && (l != 7))
-            *ret |= DH_NOT_SUITABLE_GENERATOR;
-    } else
-        *ret |= DH_UNABLE_TO_CHECK_GENERATOR;
+    }
 
     r = BN_is_prime_ex(dh->p, DH_NUMBER_ITERATIONS_FOR_PRIME, ctx, NULL);
     if (r < 0)
@@ -180,7 +164,8 @@ int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key)
 {
     int errflags = 0;
 
-    (void)DH_check(dh, &errflags);
+    if (!DH_check_pub_key(dh, pub_key, &errflags))
+        return 0;
 
     if ((errflags & DH_CHECK_PUBKEY_TOO_SMALL) != 0)
         DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_TOO_SMALL);
index 887fc4c..d293835 100644 (file)
@@ -30,30 +30,33 @@ int DH_generate_parameters_ex(DH *ret, int prime_len, int generator,
 
 /*-
  * We generate DH parameters as follows
- * find a prime q which is prime_len/2 bits long.
- * p=(2*q)+1 or (p-1)/2 = q
- * For this case, g is a generator if
- * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
- * Since the factors of p-1 are q and 2, we just need to check
- * g^2 mod p != 1 and g^q mod p != 1.
+ * find a prime p which is prime_len bits long,
+ * where q=(p-1)/2 is also prime.
+ * In the following we assume that g is not 0, 1 or p-1, since it
+ * would generate only trivial subgroups.
+ * For this case, g is a generator of the order-q subgroup if
+ * g^q mod p == 1.
+ * Or in terms of the Legendre symbol: (g/p) == 1.
  *
  * Having said all that,
  * there is another special case method for the generators 2, 3 and 5.
- * for 2, p mod 24 == 11
- * for 3, p mod 12 == 5  <<<<< does not work for safe primes.
- * for 5, p mod 10 == 3 or 7
+ * Using the quadratic reciprocity law it is possible to solve
+ * (g/p) == 1 for the special values 2, 3, 5:
+ * (2/p) == 1 if p mod 8 == 1 or 7.
+ * (3/p) == 1 if p mod 12 == 1 or 11.
+ * (5/p) == 1 if p mod 5 == 1 or 4.
+ * See for instance: https://en.wikipedia.org/wiki/Legendre_symbol
  *
- * Thanks to Phil Karn for the pointers about the
- * special generators and for answering some of my questions.
+ * Since all safe primes > 7 must satisfy p mod 12 == 11
+ * and all safe primes > 11 must satisfy p mod 5 != 1
+ * we can further improve the condition for g = 2, 3 and 5:
+ * for 2, p mod 24 == 23
+ * for 3, p mod 12 == 11
+ * for 5, p mod 60 == 59
  *
- * I've implemented the second simple method :-).
- * Since DH should be using a safe prime (both p and q are prime),
- * this generator function can take a very very long time to run.
- */
-/*
- * Actually there is no reason to insist that 'generator' be a generator.
- * It's just as OK (and in some sense better) to use a generator of the
- * order-q subgroup.
+ * However for compatibilty with previous versions we use:
+ * for 2, p mod 24 == 11
+ * for 5, p mod 60 == 23
  */
 static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
                                 BN_GENCB *cb)
@@ -88,13 +91,10 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
             goto err;
         g = 2;
     } else if (generator == DH_GENERATOR_5) {
-        if (!BN_set_word(t1, 10))
+        if (!BN_set_word(t1, 60))
             goto err;
-        if (!BN_set_word(t2, 3))
+        if (!BN_set_word(t2, 23))
             goto err;
-        /*
-         * BN_set_word(t3,7); just have to miss out on these ones :-(
-         */
         g = 5;
     } else {
         /*
@@ -102,9 +102,9 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
          * not: since we are using safe primes, it will generate either an
          * order-q or an order-2q group, which both is OK
          */
-        if (!BN_set_word(t1, 2))
+        if (!BN_set_word(t1, 12))
             goto err;
-        if (!BN_set_word(t2, 1))
+        if (!BN_set_word(t2, 11))
             goto err;
         g = generator;
     }
index 99c00e5..718aa42 100644 (file)
@@ -125,6 +125,15 @@ static int generate_key(DH *dh)
             l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
             if (!BN_priv_rand(priv_key, l, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
                 goto err;
+            /*
+             * We handle just one known case where g is a quadratic non-residue:
+             * for g = 2: p % 8 == 3
+             */
+            if (BN_is_word(dh->g, DH_GENERATOR_2) && !BN_is_bit_set(dh->p, 2)) {
+                /* clear bit 0, since it won't be a secret anyway */
+                if (!BN_clear_bit(priv_key, 0))
+                    goto err;
+            }
         }
     }
 
@@ -136,11 +145,11 @@ static int generate_key(DH *dh)
         BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
 
         if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) {
-            BN_free(prk);
+            BN_clear_free(prk);
             goto err;
         }
         /* We MUST free prk before any further use of priv_key */
-        BN_free(prk);
+        BN_clear_free(prk);
     }
 
     dh->pub_key = pub_key;
index 962f864..e7e7ef0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -234,11 +234,11 @@ void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
 int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
 {
     if (pub_key != NULL) {
-        BN_free(dh->pub_key);
+        BN_clear_free(dh->pub_key);
         dh->pub_key = pub_key;
     }
     if (priv_key != NULL) {
-        BN_free(dh->priv_key);
+        BN_clear_free(dh->priv_key);
         dh->priv_key = priv_key;
     }
 
index 9c5b8aa..49aa1ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -503,7 +503,7 @@ static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
 
     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
         *(int *)arg2 = NID_sha256;
-        return 2;
+        return 1;
 
     default:
         return -2;
index 8f97f6f..8dcf054 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -52,6 +52,8 @@ static const ERR_STRING_DATA DSA_str_reasons[] = {
     "invalid digest type"},
     {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_INVALID_PARAMETERS), "invalid parameters"},
     {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PARAMETERS), "missing parameters"},
+    {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PRIVATE_KEY),
+    "missing private key"},
     {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MODULUS_TOO_LARGE), "modulus too large"},
     {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NO_PARAMETERS_SET), "no parameters set"},
     {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_PARAMETER_ENCODING_ERROR),
index cefda5a..16161dc 100644 (file)
@@ -72,6 +72,10 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
         reason = DSA_R_MISSING_PARAMETERS;
         goto err;
     }
+    if (dsa->priv_key == NULL) {
+        reason = DSA_R_MISSING_PRIVATE_KEY;
+        goto err;
+    }
 
     ret = DSA_SIG_new();
     if (ret == NULL)
@@ -195,6 +199,10 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
         DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_PARAMETERS);
         return 0;
     }
+    if (dsa->priv_key == NULL) {
+        DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PRIVATE_KEY);
+        return 0;
+    }
 
     k = BN_new();
     l = BN_new();
@@ -248,7 +256,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
      * one bit longer than the modulus.
      *
      * There are some concerns about the efficacy of doing this.  More
-     * specificly refer to the discussion starting with:
+     * specifically refer to the discussion starting with:
      *     https://github.com/openssl/openssl/pull/7486#discussion_r228323705
      * The fix is to rework BN so these gymnastics aren't required.
      */
index 4240f5f..ba3b55f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -27,8 +27,7 @@
 #  endif
 #  include <dlfcn.h>
 #  define HAVE_DLINFO 1
-#  if defined(__CYGWIN__) || \
-     defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
+#  if defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
      (defined(__osf__) && !defined(RTLD_NEXT))     || \
      (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \
         defined(__ANDROID__)
index 0a4def6..4383bea 100755 (executable)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -2301,7 +2301,6 @@ my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
 # !in1infty, !in2infty and result of check for zero.
 
 $code.=<<___;
-.globl ecp_nistz256_point_add_vis3
 .align 32
 ecp_nistz256_point_add_vis3:
        save    %sp,-STACK64_FRAME-32*18-32,%sp
index 87149e7..10ccc64 100755 (executable)
@@ -1301,7 +1301,7 @@ ecp_nistz256_ord_mul_montx:
 
        ################################# reduction
        mulx    8*0+128(%r14), $t0, $t1
-       adcx    $t0, $acc3              # guranteed to be zero
+       adcx    $t0, $acc3              # guaranteed to be zero
        adox    $t1, $acc4
 
        mulx    8*1+128(%r14), $t0, $t1
index 3773cb2..6e8b364 100755 (executable)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -451,7 +451,7 @@ x25519_fe64_tobytes:
        and     $t0,$t0,$t1
        sldi    $a3,$a3,1
        add     $t0,$t0,$t1             # compare to modulus in the same go
-       srdi    $a3,$a3,1               # most signifcant bit cleared
+       srdi    $a3,$a3,1               # most significant bit cleared
 
        addc    $a0,$a0,$t0
        addze   $a1,$a1
@@ -462,7 +462,7 @@ x25519_fe64_tobytes:
        sradi   $t0,$a3,63              # most significant bit -> mask
        sldi    $a3,$a3,1
        andc    $t0,$t1,$t0
-       srdi    $a3,$a3,1               # most signifcant bit cleared
+       srdi    $a3,$a3,1               # most significant bit cleared
 
        subi    $rp,$rp,1
        subfc   $a0,$t0,$a0
index 13c56a6..1ce1181 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -568,10 +568,12 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
 EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
 {
     int ok = 0, tmp;
-    EC_GROUP *ret = NULL;
+    EC_GROUP *ret = NULL, *dup = NULL;
     BIGNUM *p = NULL, *a = NULL, *b = NULL;
     EC_POINT *point = NULL;
     long field_bits;
+    int curve_name = NID_undef;
+    BN_CTX *ctx = NULL;
 
     if (!params->fieldID || !params->fieldID->fieldType ||
         !params->fieldID->p.ptr) {
@@ -789,18 +791,79 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
         goto err;
     }
 
+    /*
+     * Check if the explicit parameters group just created matches one of the
+     * built-in curves.
+     *
+     * We create a copy of the group just built, so that we can remove optional
+     * fields for the lookup: we do this to avoid the possibility that one of
+     * the optional parameters is used to force the library into using a less
+     * performant and less secure EC_METHOD instead of the specialized one.
+     * In any case, `seed` is not really used in any computation, while a
+     * cofactor different from the one in the built-in table is just
+     * mathematically wrong anyway and should not be used.
+     */
+    if ((ctx = BN_CTX_new()) == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB);
+        goto err;
+    }
+    if ((dup = EC_GROUP_dup(ret)) == NULL
+            || EC_GROUP_set_seed(dup, NULL, 0) != 1
+            || !EC_GROUP_set_generator(dup, point, a, NULL)) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+        goto err;
+    }
+    if ((curve_name = ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
+        /*
+         * The input explicit parameters successfully matched one of the
+         * built-in curves: often for built-in curves we have specialized
+         * methods with better performance and hardening.
+         *
+         * In this case we replace the `EC_GROUP` created through explicit
+         * parameters with one created from a named group.
+         */
+        EC_GROUP *named_group = NULL;
+
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+        /*
+         * NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for
+         * the same curve, we prefer the SECP nid when matching explicit
+         * parameters as that is associated with a specialized EC_METHOD.
+         */
+        if (curve_name == NID_wap_wsg_idm_ecid_wtls12)
+            curve_name = NID_secp224r1;
+#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
+
+        if ((named_group = EC_GROUP_new_by_curve_name(curve_name)) == NULL) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+            goto err;
+        }
+        EC_GROUP_free(ret);
+        ret = named_group;
+
+        /*
+         * Set the flag so that EC_GROUPs created from explicit parameters are
+         * serialized using explicit parameters by default.
+         */
+        EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE);
+    }
+
     ok = 1;
 
  err:
     if (!ok) {
-        EC_GROUP_clear_free(ret);
+        EC_GROUP_free(ret);
         ret = NULL;
     }
+    EC_GROUP_free(dup);
 
     BN_free(p);
     BN_free(a);
     BN_free(b);
     EC_POINT_free(point);
+
+    BN_CTX_free(ctx);
+
     return ret;
 }
 
@@ -861,7 +924,7 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
     }
 
     if (a) {
-        EC_GROUP_clear_free(*a);
+        EC_GROUP_free(*a);
         *a = group;
     }
 
@@ -909,7 +972,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
         ret = *a;
 
     if (priv_key->parameters) {
-        EC_GROUP_clear_free(ret->group);
+        EC_GROUP_free(ret->group);
         ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters);
     }
 
index bb1ce19..477349d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
@@ -3197,3 +3197,115 @@ int EC_curve_nist2nid(const char *name)
     }
     return NID_undef;
 }
+
+#define NUM_BN_FIELDS 6
+/*
+ * Validates EC domain parameter data for known named curves.
+ * This can be used when a curve is loaded explicitly (without a curve
+ * name) or to validate that domain parameters have not been modified.
+ *
+ * Returns: The nid associated with the found named curve, or NID_undef
+ *          if not found. If there was an error it returns -1.
+ */
+int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
+{
+    int ret = -1, nid, len, field_type, param_len;
+    size_t i, seed_len;
+    const unsigned char *seed, *params_seed, *params;
+    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);
+    seed_len = EC_GROUP_get_seed_len(group);
+    seed = EC_GROUP_get0_seed(group);
+    cofactor = EC_GROUP_get0_cofactor(group);
+
+    BN_CTX_start(ctx);
+
+    /*
+     * The built-in curves contains data fields (p, a, b, x, y, order) that are
+     * all zero-padded to be the same size. The size of the padding is
+     * determined by either the number of bytes in the field modulus (p) or the
+     * EC group order, whichever is larger.
+     */
+    param_len = BN_num_bytes(group->order);
+    len = BN_num_bytes(group->field);
+    if (len > param_len)
+        param_len = len;
+
+    /* Allocate space to store the padded data for (p, a, b, x, y, order)  */
+    param_bytes = OPENSSL_malloc(param_len * NUM_BN_FIELDS);
+    if (param_bytes == NULL)
+        goto end;
+
+    /* Create the bignums */
+    for (i = 0; i < NUM_BN_FIELDS; ++i) {
+        if ((bn[i] = BN_CTX_get(ctx)) == NULL)
+            goto end;
+    }
+    /*
+     * Fill in the bn array with the same values as the internal curves
+     * i.e. the values are p, a, b, x, y, order.
+     */
+    /* Get p, a & b */
+    if (!(EC_GROUP_get_curve(group, bn[0], bn[1], bn[2], ctx)
+        && ((generator = EC_GROUP_get0_generator(group)) != NULL)
+        /* Get x & y */
+        && EC_POINT_get_affine_coordinates(group, generator, bn[3], bn[4], ctx)
+        /* Get order */
+        && EC_GROUP_get_order(group, bn[5], ctx)))
+        goto end;
+
+   /*
+     * Convert the bignum array to bytes that are joined together to form
+     * a single buffer that contains data for all fields.
+     * (p, a, b, x, y, order) are all zero padded to be the same size.
+     */
+    for (i = 0; i < NUM_BN_FIELDS; ++i) {
+        if (BN_bn2binpad(bn[i], &param_bytes[i*param_len], param_len) <= 0)
+            goto end;
+    }
+
+    for (i = 0; i < curve_list_length; i++) {
+        const ec_list_element curve = curve_list[i];
+
+        data = curve.data;
+        /* Get the raw order byte data */
+        params_seed = (const unsigned char *)(data + 1); /* skip header */
+        params = params_seed + data->seed_len;
+
+        /* Look for unique fields in the fixed curve data */
+        if (data->field_type == field_type
+            && param_len == data->param_len
+            && (nid <= 0 || nid == curve.nid)
+            /* check the optional cofactor (ignore if its zero) */
+            && (BN_is_zero(cofactor)
+                || BN_is_word(cofactor, (const BN_ULONG)curve.data->cofactor))
+            /* Check the optional seed (ignore if its not set) */
+            && (data->seed_len == 0 || seed_len == 0
+                || ((size_t)data->seed_len == seed_len
+                     && memcmp(params_seed, seed, seed_len) == 0))
+            /* Check that the groups params match the built-in curve params */
+            && memcmp(param_bytes, params, param_len * NUM_BN_FIELDS)
+                             == 0) {
+            ret = curve.nid;
+            goto end;
+        }
+    }
+    /* Gets here if the group was not found */
+    ret = NID_undef;
+end:
+    OPENSSL_free(param_bytes);
+    BN_CTX_end(ctx);
+    return ret;
+}
index 119255f..fbdb04e 100644 (file)
@@ -154,7 +154,7 @@ struct ec_method_st {
     int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
                       const BIGNUM *b, BN_CTX *);
     /*-
-     * 'field_inv' computes the multipicative inverse of a in the field,
+     * 'field_inv' computes the multiplicative inverse of a in the field,
      * storing the result in r.
      *
      * If 'a' is zero (or equivalent), you'll get an EC_R_CANNOT_INVERT error.
@@ -595,6 +595,8 @@ int ec_key_simple_generate_key(EC_KEY *eckey);
 int ec_key_simple_generate_public_key(EC_KEY *eckey);
 int ec_key_simple_check_key(const EC_KEY *eckey);
 
+int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx);
+
 /* EC_METHOD definitions */
 
 struct ec_key_method_st {
index 8cab5a5..1289c86 100644 (file)
@@ -265,6 +265,67 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth)
 
 static int ec_precompute_mont_data(EC_GROUP *);
 
+/*-
+ * Try computing cofactor from the generator order (n) and field cardinality (q).
+ * This works for all curves of cryptographic interest.
+ *
+ * Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q)
+ * h_min = (q + 1 - 2*sqrt(q))/n
+ * h_max = (q + 1 + 2*sqrt(q))/n
+ * h_max - h_min = 4*sqrt(q)/n
+ * So if n > 4*sqrt(q) holds, there is only one possible value for h:
+ * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil
+ *
+ * Otherwise, zero cofactor and return success.
+ */
+static int ec_guess_cofactor(EC_GROUP *group) {
+    int ret = 0;
+    BN_CTX *ctx = NULL;
+    BIGNUM *q = NULL;
+
+    /*-
+     * If the cofactor is too large, we cannot guess it.
+     * The RHS of below is a strict overestimate of lg(4 * sqrt(q))
+     */
+    if (BN_num_bits(group->order) <= (BN_num_bits(group->field) + 1) / 2 + 3) {
+        /* default to 0 */
+        BN_zero(group->cofactor);
+        /* return success */
+        return 1;
+    }
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        return 0;
+
+    BN_CTX_start(ctx);
+    if ((q = BN_CTX_get(ctx)) == NULL)
+        goto err;
+
+    /* set q = 2**m for binary fields; q = p otherwise */
+    if (group->meth->field_type == NID_X9_62_characteristic_two_field) {
+        BN_zero(q);
+        if (!BN_set_bit(q, BN_num_bits(group->field) - 1))
+            goto err;
+    } else {
+        if (!BN_copy(q, group->field))
+            goto err;
+    }
+
+    /* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */
+    if (!BN_rshift1(group->cofactor, group->order) /* n/2 */
+        || !BN_add(group->cofactor, group->cofactor, q) /* q + n/2 */
+        /* q + 1 + n/2 */
+        || !BN_add(group->cofactor, group->cofactor, BN_value_one())
+        /* (q + 1 + n/2)/n */
+        || !BN_div(group->cofactor, NULL, group->cofactor, group->order, ctx))
+        goto err;
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    return ret;
+}
+
 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
                            const BIGNUM *order, const BIGNUM *cofactor)
 {
@@ -273,6 +334,34 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
         return 0;
     }
 
+    /* require group->field >= 1 */
+    if (group->field == NULL || BN_is_zero(group->field)
+        || BN_is_negative(group->field)) {
+        ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD);
+        return 0;
+    }
+
+    /*-
+     * - require order >= 1
+     * - enforce upper bound due to Hasse thm: order can be no more than one bit
+     *   longer than field cardinality
+     */
+    if (order == NULL || BN_is_zero(order) || BN_is_negative(order)
+        || BN_num_bits(order) > BN_num_bits(group->field) + 1) {
+        ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER);
+        return 0;
+    }
+
+    /*-
+     * Unfortunately the cofactor is an optional field in many standards.
+     * Internally, the lib uses 0 cofactor as a marker for "unknown cofactor".
+     * So accept cofactor == NULL or cofactor >= 0.
+     */
+    if (cofactor != NULL && BN_is_negative(cofactor)) {
+        ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR);
+        return 0;
+    }
+
     if (group->generator == NULL) {
         group->generator = EC_POINT_new(group);
         if (group->generator == NULL)
@@ -281,17 +370,17 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
     if (!EC_POINT_copy(group->generator, generator))
         return 0;
 
-    if (order != NULL) {
-        if (!BN_copy(group->order, order))
-            return 0;
-    } else
-        BN_zero(group->order);
+    if (!BN_copy(group->order, order))
+        return 0;
 
-    if (cofactor != NULL) {
+    /* Either take the provided positive cofactor, or try to compute it */
+    if (cofactor != NULL && !BN_is_zero(cofactor)) {
         if (!BN_copy(group->cofactor, cofactor))
             return 0;
-    } else
+    } else if (!ec_guess_cofactor(group)) {
         BN_zero(group->cofactor);
+        return 0;
+    }
 
     /*
      * Some groups have an order with
index 5608c62..ab51ee7 100644 (file)
@@ -58,7 +58,7 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
 
     priv_key = EC_KEY_get0_private_key(ecdh);
     if (priv_key == NULL) {
-        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_NO_PRIVATE_VALUE);
+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_MISSING_PRIVATE_KEY);
         goto err;
     }
 
index e35c760..c35ed2d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -41,11 +41,16 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
     const EC_GROUP *group;
     int ret = 0;
     int order_bits;
+    const BIGNUM *priv_key;
 
     if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
         ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
         return 0;
     }
+    if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL) {
+        ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_MISSING_PRIVATE_KEY);
+        return 0;
+    }
 
     if (!EC_KEY_can_sign(eckey)) {
         ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
@@ -83,8 +88,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
         /* get random k */
         do {
             if (dgst != NULL) {
-                if (!BN_generate_dsa_nonce(k, order,
-                                           EC_KEY_get0_private_key(eckey),
+                if (!BN_generate_dsa_nonce(k, order, priv_key,
                                            dgst, dlen, ctx)) {
                     ECerr(EC_F_ECDSA_SIGN_SETUP,
                           EC_R_RANDOM_NUMBER_GENERATION_FAILED);
@@ -162,10 +166,14 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
     group = EC_KEY_get0_group(eckey);
     priv_key = EC_KEY_get0_private_key(eckey);
 
-    if (group == NULL || priv_key == NULL) {
+    if (group == NULL) {
         ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER);
         return NULL;
     }
+    if (priv_key == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_MISSING_PRIVATE_KEY);
+        return NULL;
+    }
 
     if (!EC_KEY_can_sign(eckey)) {
         ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
index 025273a..fbbdb9d 100644 (file)
@@ -324,34 +324,21 @@ static void felem_to_bin28(u8 out[28], const felem in)
     }
 }
 
-/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-static void flip_endian(u8 *out, const u8 *in, unsigned len)
-{
-    unsigned i;
-    for (i = 0; i < len; ++i)
-        out[i] = in[len - 1 - i];
-}
-
 /* From OpenSSL BIGNUM to internal representation */
 static int BN_to_felem(felem out, const BIGNUM *bn)
 {
-    felem_bytearray b_in;
     felem_bytearray b_out;
-    unsigned num_bytes;
+    int num_bytes;
 
-    /* BN_bn2bin eats leading zeroes */
-    memset(b_out, 0, sizeof(b_out));
-    num_bytes = BN_num_bytes(bn);
-    if (num_bytes > sizeof(b_out)) {
+    if (BN_is_negative(bn)) {
         ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
         return 0;
     }
-    if (BN_is_negative(bn)) {
+    num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out));
+    if (num_bytes < 0) {
         ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
         return 0;
     }
-    num_bytes = BN_bn2bin(bn, b_in);
-    flip_endian(b_out, b_in, num_bytes);
     bin28_to_felem(out, b_out);
     return 1;
 }
@@ -359,10 +346,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
 /* From internal representation to OpenSSL BIGNUM */
 static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
 {
-    felem_bytearray b_in, b_out;
-    felem_to_bin28(b_in, in);
-    flip_endian(b_out, b_in, sizeof(b_out));
-    return BN_bin2bn(b_out, sizeof(b_out), out);
+    felem_bytearray b_out;
+    felem_to_bin28(b_out, in);
+    return BN_lebin2bn(b_out, sizeof(b_out), out);
 }
 
 /******************************************************************************/
@@ -1402,8 +1388,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
     felem_bytearray *secrets = NULL;
     felem (*pre_comp)[17][3] = NULL;
     felem *tmp_felems = NULL;
-    felem_bytearray tmp;
-    unsigned num_bytes;
+    int num_bytes;
     int have_pre_comp = 0;
     size_t num_points = num;
     felem x_in, y_in, z_in, x_out, y_out, z_out;
@@ -1478,14 +1463,12 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
          * i.e., they contribute nothing to the linear combination
          */
         for (i = 0; i < num_points; ++i) {
-            if (i == num)
+            if (i == num) {
                 /* the generator */
-            {
                 p = EC_GROUP_get0_generator(group);
                 p_scalar = scalar;
-            } else
+            } else {
                 /* the i^th point */
-            {
                 p = points[i];
                 p_scalar = scalars[i];
             }
@@ -1501,10 +1484,16 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
                         ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
                         goto err;
                     }
-                    num_bytes = BN_bn2bin(tmp_scalar, tmp);
-                } else
-                    num_bytes = BN_bn2bin(p_scalar, tmp);
-                flip_endian(secrets[i], tmp, num_bytes);
+                    num_bytes = BN_bn2lebinpad(tmp_scalar,
+                                               secrets[i], sizeof(secrets[i]));
+                } else {
+                    num_bytes = BN_bn2lebinpad(p_scalar,
+                                               secrets[i], sizeof(secrets[i]));
+                }
+                if (num_bytes < 0) {
+                    ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+                    goto err;
+                }
                 /* precompute multiples */
                 if ((!BN_to_felem(x_out, p->X)) ||
                     (!BN_to_felem(y_out, p->Y)) ||
@@ -1547,20 +1536,21 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
                 ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
                 goto err;
             }
-            num_bytes = BN_bn2bin(tmp_scalar, tmp);
-        } else
-            num_bytes = BN_bn2bin(scalar, tmp);
-        flip_endian(g_secret, tmp, num_bytes);
+            num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
+        } else {
+            num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
+        }
         /* do the multiplication with generator precomputation */
         batch_mul(x_out, y_out, z_out,
                   (const felem_bytearray(*))secrets, num_points,
                   g_secret,
                   mixed, (const felem(*)[17][3])pre_comp, g_pre_comp);
-    } else
+    } else {
         /* do the multiplication without generator precomputation */
         batch_mul(x_out, y_out, z_out,
                   (const felem_bytearray(*))secrets, num_points,
                   NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+    }
     /* reduce the output to its unique minimal representation */
     felem_contract(x_in, x_out);
     felem_contract(y_in, y_out);
index a21e5f7..22ba69a 100644 (file)
@@ -146,34 +146,21 @@ static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
     *((u64 *)&out[24]) = in[3];
 }
 
-/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-static void flip_endian(u8 *out, const u8 *in, unsigned len)
-{
-    unsigned i;
-    for (i = 0; i < len; ++i)
-        out[i] = in[len - 1 - i];
-}
-
 /* BN_to_felem converts an OpenSSL BIGNUM into an felem */
 static int BN_to_felem(felem out, const BIGNUM *bn)
 {
-    felem_bytearray b_in;
     felem_bytearray b_out;
-    unsigned num_bytes;
+    int num_bytes;
 
-    /* BN_bn2bin eats leading zeroes */
-    memset(b_out, 0, sizeof(b_out));
-    num_bytes = BN_num_bytes(bn);
-    if (num_bytes > sizeof(b_out)) {
+    if (BN_is_negative(bn)) {
         ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
         return 0;
     }
-    if (BN_is_negative(bn)) {
+    num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out));
+    if (num_bytes < 0) {
         ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
         return 0;
     }
-    num_bytes = BN_bn2bin(bn, b_in);
-    flip_endian(b_out, b_in, num_bytes);
     bin32_to_felem(out, b_out);
     return 1;
 }
@@ -181,10 +168,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
 /* felem_to_BN converts an felem into an OpenSSL BIGNUM */
 static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
 {
-    felem_bytearray b_in, b_out;
-    smallfelem_to_bin32(b_in, in);
-    flip_endian(b_out, b_in, sizeof(b_out));
-    return BN_bin2bn(b_out, sizeof(b_out), out);
+    felem_bytearray b_out;
+    smallfelem_to_bin32(b_out, in);
+    return BN_lebin2bn(b_out, sizeof(b_out), out);
 }
 
 /*-
@@ -2024,8 +2010,8 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
     felem_bytearray *secrets = NULL;
     smallfelem (*pre_comp)[17][3] = NULL;
     smallfelem *tmp_smallfelems = NULL;
-    felem_bytearray tmp;
-    unsigned i, num_bytes;
+    unsigned i;
+    int num_bytes;
     int have_pre_comp = 0;
     size_t num_points = num;
     smallfelem x_in, y_in, z_in;
@@ -2102,17 +2088,15 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
         memset(secrets, 0, sizeof(*secrets) * num_points);
         memset(pre_comp, 0, sizeof(*pre_comp) * num_points);
         for (i = 0; i < num_points; ++i) {
-            if (i == num)
+            if (i == num) {
                 /*
                  * we didn't have a valid precomputation, so we pick the
                  * generator
                  */
-            {
                 p = EC_GROUP_get0_generator(group);
                 p_scalar = scalar;
-            } else
+            } else {
                 /* the i^th point */
-            {
                 p = points[i];
                 p_scalar = scalars[i];
             }
@@ -2128,10 +2112,16 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
                         ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
                         goto err;
                     }
-                    num_bytes = BN_bn2bin(tmp_scalar, tmp);
-                } else
-                    num_bytes = BN_bn2bin(p_scalar, tmp);
-                flip_endian(secrets[i], tmp, num_bytes);
+                    num_bytes = BN_bn2lebinpad(tmp_scalar,
+                                               secrets[i], sizeof(secrets[i]));
+                } else {
+                    num_bytes = BN_bn2lebinpad(p_scalar,
+                                               secrets[i], sizeof(secrets[i]));
+                }
+                if (num_bytes < 0) {
+                    ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+                    goto err;
+                }
                 /* precompute multiples */
                 if ((!BN_to_felem(x_out, p->X)) ||
                     (!BN_to_felem(y_out, p->Y)) ||
@@ -2176,20 +2166,21 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
                 ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
                 goto err;
             }
-            num_bytes = BN_bn2bin(tmp_scalar, tmp);
-        } else
-            num_bytes = BN_bn2bin(scalar, tmp);
-        flip_endian(g_secret, tmp, num_bytes);
+            num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
+        } else {
+            num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
+        }
         /* do the multiplication with generator precomputation */
         batch_mul(x_out, y_out, z_out,
                   (const felem_bytearray(*))secrets, num_points,
                   g_secret,
                   mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp);
-    } else
+    } else {
         /* do the multiplication without generator precomputation */
         batch_mul(x_out, y_out, z_out,
                   (const felem_bytearray(*))secrets, num_points,
                   NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL);
+    }
     /* reduce the output to its unique minimal representation */
     felem_contract(x_in, x_out);
     felem_contract(y_in, y_out);
index e31b85c..6340f48 100644 (file)
@@ -169,34 +169,21 @@ static void felem_to_bin66(u8 out[66], const felem in)
     (*((limb *) & out[58])) = in[8];
 }
 
-/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-static void flip_endian(u8 *out, const u8 *in, unsigned len)
-{
-    unsigned i;
-    for (i = 0; i < len; ++i)
-        out[i] = in[len - 1 - i];
-}
-
 /* BN_to_felem converts an OpenSSL BIGNUM into an felem */
 static int BN_to_felem(felem out, const BIGNUM *bn)
 {
-    felem_bytearray b_in;
     felem_bytearray b_out;
-    unsigned num_bytes;
+    int num_bytes;
 
-    /* BN_bn2bin eats leading zeroes */
-    memset(b_out, 0, sizeof(b_out));
-    num_bytes = BN_num_bytes(bn);
-    if (num_bytes > sizeof(b_out)) {
+    if (BN_is_negative(bn)) {
         ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
         return 0;
     }
-    if (BN_is_negative(bn)) {
+    num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out));
+    if (num_bytes < 0) {
         ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
         return 0;
     }
-    num_bytes = BN_bn2bin(bn, b_in);
-    flip_endian(b_out, b_in, num_bytes);
     bin66_to_felem(out, b_out);
     return 1;
 }
@@ -204,10 +191,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
 /* felem_to_BN converts an felem into an OpenSSL BIGNUM */
 static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
 {
-    felem_bytearray b_in, b_out;
-    felem_to_bin66(b_in, in);
-    flip_endian(b_out, b_in, sizeof(b_out));
-    return BN_bin2bn(b_out, sizeof(b_out), out);
+    felem_bytearray b_out;
+    felem_to_bin66(b_out, in);
+    return BN_lebin2bn(b_out, sizeof(b_out), out);
 }
 
 /*-
@@ -1269,7 +1255,7 @@ static void point_add(felem x3, felem y3, felem z3,
          * ffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb
          * 71e913863f7, in that case the penultimate intermediate is -9G and
          * the final digit is also -9G. Since this only happens for a single
-         * scalar, the timing leak is irrelevent. (Any attacker who wanted to
+         * scalar, the timing leak is irrelevant. (Any attacker who wanted to
          * check whether a secret scalar was that exact value, can already do
          * so.)
          */
@@ -1866,8 +1852,8 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
     felem_bytearray *secrets = NULL;
     felem (*pre_comp)[17][3] = NULL;
     felem *tmp_felems = NULL;
-    felem_bytearray tmp;
-    unsigned i, num_bytes;
+    unsigned i;
+    int num_bytes;
     int have_pre_comp = 0;
     size_t num_points = num;
     felem x_in, y_in, z_in, x_out, y_out, z_out;
@@ -1942,17 +1928,15 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
          * i.e., they contribute nothing to the linear combination
          */
         for (i = 0; i < num_points; ++i) {
-            if (i == num)
+            if (i == num) {
                 /*
                  * we didn't have a valid precomputation, so we pick the
                  * generator
                  */
-            {
                 p = EC_GROUP_get0_generator(group);
                 p_scalar = scalar;
-            } else
+            } else {
                 /* the i^th point */
-            {
                 p = points[i];
                 p_scalar = scalars[i];
             }
@@ -1968,10 +1952,16 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
                         ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
                         goto err;
                     }
-                    num_bytes = BN_bn2bin(tmp_scalar, tmp);
-                } else
-                    num_bytes = BN_bn2bin(p_scalar, tmp);
-                flip_endian(secrets[i], tmp, num_bytes);
+                    num_bytes = BN_bn2lebinpad(tmp_scalar,
+                                               secrets[i], sizeof(secrets[i]));
+                } else {
+                    num_bytes = BN_bn2lebinpad(p_scalar,
+                                               secrets[i], sizeof(secrets[i]));
+                }
+                if (num_bytes < 0) {
+                    ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+                    goto err;
+                }
                 /* precompute multiples */
                 if ((!BN_to_felem(x_out, p->X)) ||
                     (!BN_to_felem(y_out, p->Y)) ||
@@ -2014,21 +2004,22 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
                 ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
                 goto err;
             }
-            num_bytes = BN_bn2bin(tmp_scalar, tmp);
-        } else
-            num_bytes = BN_bn2bin(scalar, tmp);
-        flip_endian(g_secret, tmp, num_bytes);
+            num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
+        } else {
+            num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
+        }
         /* do the multiplication with generator precomputation */
         batch_mul(x_out, y_out, z_out,
                   (const felem_bytearray(*))secrets, num_points,
                   g_secret,
                   mixed, (const felem(*)[17][3])pre_comp,
                   (const felem(*)[3])g_pre_comp);
-    } else
+    } else {
         /* do the multiplication without generator precomputation */
         batch_mul(x_out, y_out, z_out,
                   (const felem_bytearray(*))secrets, num_points,
                   NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+    }
     /* reduce the output to its unique minimal representation */
     felem_contract(x_in, x_out);
     felem_contract(y_in, y_out);
index 97fb631..f89a2f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2011-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -158,13 +158,13 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
  *     of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
  *     by using bit-wise subtraction as follows:
  *
- *        b_k b_(k-1)  ...  b_2  b_1  b_0
- *      -     b_k      ...  b_3  b_2  b_1  b_0
- *       -------------------------------------
- *        s_k b_(k-1)  ...  s_3  s_2  s_1  s_0
+ *        b_k     b_(k-1)  ...  b_2  b_1  b_0
+ *      -         b_k      ...  b_3  b_2  b_1  b_0
+ *       -----------------------------------------
+ *        s_(k+1) s_k      ...  s_3  s_2  s_1  s_0
  *
  *     A left-shift followed by subtraction of the original value yields a new
- *     representation of the same value, using signed bits s_i = b_(i+1) - b_i.
+ *     representation of the same value, using signed bits s_i = b_(i-1) - b_i.
  *     This representation from Booth's paper has since appeared in the
  *     literature under a variety of different names including "reversed binary
  *     form", "alternating greedy expansion", "mutual opposite form", and
@@ -188,7 +188,7 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
  * (1961), pp. 67-91), in a radix-2^5 setting.  That is, we always combine five
  * signed bits into a signed digit:
  *
- *       s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
+ *       s_(5j + 4) s_(5j + 3) s_(5j + 2) s_(5j + 1) s_(5j)
  *
  * The sign-alternating property implies that the resulting digit values are
  * integers from -16 to 16.
@@ -196,14 +196,14 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
  * Of course, we don't actually need to compute the signed digits s_i as an
  * intermediate step (that's just a nice way to see how this scheme relates
  * to the wNAF): a direct computation obtains the recoded digit from the
- * six bits b_(4j + 4) ... b_(4j - 1).
+ * six bits b_(5j + 4) ... b_(5j - 1).
  *
- * This function takes those five bits as an integer (0 .. 63), writing the
+ * This function takes those six bits as an integer (0 .. 63), writing the
  * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
- * value, in the range 0 .. 8).  Note that this integer essentially provides the
- * input bits "shifted to the left" by one position: for example, the input to
- * compute the least significant recoded digit, given that there's no bit b_-1,
- * has to be b_4 b_3 b_2 b_1 b_0 0.
+ * value, in the range 0 .. 16).  Note that this integer essentially provides
+ * the input bits "shifted to the left" by one position: for example, the input
+ * to compute the least significant recoded digit, given that there's no bit
+ * b_-1, has to be b_4 b_3 b_2 b_1 b_0 0.
  *
  */
 void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
index e4cac99..c87419b 100644 (file)
@@ -532,7 +532,7 @@ static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
     X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
     if (alg2)
         X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
-    /* Algorithm idetifiers set: carry on as normal */
+    /* Algorithm identifiers set: carry on as normal */
     return 3;
 }
 
index 717d7c2..a727c6f 100644 (file)
@@ -26,7 +26,7 @@
 
 /* #define ENGINE_DEVCRYPTO_DEBUG */
 
-#ifdef CRYPTO_ALGORITHM_MIN
+#if CRYPTO_ALGORITHM_MIN < CRYPTO_ALGORITHM_MAX
 # define CHECK_BSD_STYLE_MACROS
 #endif
 
index f7ad7a5..d9b3067 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  */
 #define TEST_ENG_OPENSSL_RC4
 #ifndef OPENSSL_NO_STDIO
-#define TEST_ENG_OPENSSL_PKEY
+# define TEST_ENG_OPENSSL_PKEY
 #endif
 /* #define TEST_ENG_OPENSSL_HMAC */
 /* #define TEST_ENG_OPENSSL_HMAC_INIT */
 /* #define TEST_ENG_OPENSSL_RC4_OTHERS */
-#define TEST_ENG_OPENSSL_RC4_P_INIT
+#ifndef OPENSSL_NO_STDIO
+# define TEST_ENG_OPENSSL_RC4_P_INIT
+#endif
 /* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
 #define TEST_ENG_OPENSSL_SHA
 /* #define TEST_ENG_OPENSSL_SHA_OTHERS */
index eaf6712..3a58ccb 100644 (file)
@@ -184,8 +184,8 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
 }
 
 #ifndef OPENSSL_NO_ERR
-/* A measurement on Linux 2018-11-21 showed about 3.5kib */
-# define SPACE_SYS_STR_REASONS 4 * 1024
+/* 2019-05-21: Russian and Ukrainian locales on Linux require more than 6,5 kB */
+# define SPACE_SYS_STR_REASONS 8 * 1024
 # define NUM_SYS_STR_REASONS 127
 
 static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
@@ -219,21 +219,23 @@ static void build_SYS_str_reasons(void)
         ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
 
         str->error = ERR_PACK(ERR_LIB_SYS, 0, i);
-        if (str->string == NULL) {
+        /*
+         * If we have used up all the space in strerror_pool,
+         * there's no point in calling openssl_strerror_r()
+         */
+        if (str->string == NULL && cnt < sizeof(strerror_pool)) {
             if (openssl_strerror_r(i, cur, sizeof(strerror_pool) - cnt)) {
                 size_t l = strlen(cur);
 
                 str->string = cur;
                 cnt += l;
-                if (cnt > sizeof(strerror_pool))
-                    cnt = sizeof(strerror_pool);
                 cur += l;
 
                 /*
                  * VMS has an unusual quirk of adding spaces at the end of
-                 * some (most? all?) messages.  Lets trim them off.
+                 * some (most? all?) messages. Lets trim them off.
                  */
-                while (ossl_isspace(cur[-1])) {
+                while (cur > strerror_pool && ossl_isspace(cur[-1])) {
                     cur--;
                     cnt--;
                 }
index feff1dc..a433b03 100644 (file)
@@ -314,6 +314,7 @@ CMS_F_CMS_SIGNERINFO_VERIFY:152:CMS_SignerInfo_verify
 CMS_F_CMS_SIGNERINFO_VERIFY_CERT:153:cms_signerinfo_verify_cert
 CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT:154:CMS_SignerInfo_verify_content
 CMS_F_CMS_SIGN_RECEIPT:163:CMS_sign_receipt
+CMS_F_CMS_SI_CHECK_ATTRIBUTES:183:CMS_si_check_attributes
 CMS_F_CMS_STREAM:155:CMS_stream
 CMS_F_CMS_UNCOMPRESS:156:CMS_uncompress
 CMS_F_CMS_VERIFY:157:CMS_verify
@@ -713,11 +714,14 @@ ENGINE_F_INT_ENGINE_CONFIGURE:188:int_engine_configure
 ENGINE_F_INT_ENGINE_MODULE_INIT:187:int_engine_module_init
 ENGINE_F_OSSL_HMAC_INIT:200:ossl_hmac_init
 EVP_F_AESNI_INIT_KEY:165:aesni_init_key
+EVP_F_AESNI_XTS_INIT_KEY:207:aesni_xts_init_key
 EVP_F_AES_GCM_CTRL:196:aes_gcm_ctrl
 EVP_F_AES_INIT_KEY:133:aes_init_key
 EVP_F_AES_OCB_CIPHER:169:aes_ocb_cipher
 EVP_F_AES_T4_INIT_KEY:178:aes_t4_init_key
+EVP_F_AES_T4_XTS_INIT_KEY:208:aes_t4_xts_init_key
 EVP_F_AES_WRAP_CIPHER:170:aes_wrap_cipher
+EVP_F_AES_XTS_INIT_KEY:209:aes_xts_init_key
 EVP_F_ALG_MODULE_INIT:177:alg_module_init
 EVP_F_ARIA_CCM_INIT_KEY:175:aria_ccm_init_key
 EVP_F_ARIA_GCM_CTRL:197:aria_gcm_ctrl
@@ -808,6 +812,7 @@ EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN:180:PKCS5_v2_scrypt_keyivgen
 EVP_F_PKEY_SET_TYPE:158:pkey_set_type
 EVP_F_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth
 EVP_F_RC5_CTRL:125:rc5_ctrl
+EVP_F_R_32_12_16_INIT_KEY:242:r_32_12_16_init_key
 EVP_F_S390X_AES_GCM_CTRL:201:s390x_aes_gcm_ctrl
 EVP_F_UPDATE:173:update
 KDF_F_PKEY_HKDF_CTRL_STR:103:pkey_hkdf_ctrl_str
@@ -1020,6 +1025,7 @@ RAND_F_RAND_POOL_ADD_BEGIN:113:rand_pool_add_begin
 RAND_F_RAND_POOL_ADD_END:114:rand_pool_add_end
 RAND_F_RAND_POOL_ATTACH:124:rand_pool_attach
 RAND_F_RAND_POOL_BYTES_NEEDED:115:rand_pool_bytes_needed
+RAND_F_RAND_POOL_GROW:125:rand_pool_grow
 RAND_F_RAND_POOL_NEW:116:rand_pool_new
 RAND_F_RAND_WRITE_FILE:112:RAND_write_file
 RSA_F_CHECK_PADDING_MD:140:check_padding_md
@@ -1930,6 +1936,7 @@ BN_R_P_IS_NOT_PRIME:112:p is not prime
 BN_R_TOO_MANY_ITERATIONS:113:too many iterations
 BN_R_TOO_MANY_TEMPORARY_VARIABLES:109:too many temporary variables
 CMS_R_ADD_SIGNER_ERROR:99:add signer error
+CMS_R_ATTRIBUTE_ERROR:161:attribute error
 CMS_R_CERTIFICATE_ALREADY_PRESENT:175:certificate already present
 CMS_R_CERTIFICATE_HAS_NO_KEYID:160:certificate has no keyid
 CMS_R_CERTIFICATE_VERIFY_ERROR:100:certificate verify error
@@ -2094,6 +2101,7 @@ DSA_R_DECODE_ERROR:104:decode error
 DSA_R_INVALID_DIGEST_TYPE:106:invalid digest type
 DSA_R_INVALID_PARAMETERS:112:invalid parameters
 DSA_R_MISSING_PARAMETERS:101:missing parameters
+DSA_R_MISSING_PRIVATE_KEY:111:missing private key
 DSA_R_MODULUS_TOO_LARGE:103:modulus too large
 DSA_R_NO_PARAMETERS_SET:107:no parameters set
 DSA_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error
@@ -2218,6 +2226,7 @@ ENGINE_R_VERSION_INCOMPATIBILITY:145:version incompatibility
 EVP_R_AES_KEY_SETUP_FAILED:143:aes key setup failed
 EVP_R_ARIA_KEY_SETUP_FAILED:176:aria key setup failed
 EVP_R_BAD_DECRYPT:100:bad decrypt
+EVP_R_BAD_KEY_LENGTH:195:bad key length
 EVP_R_BUFFER_TOO_SMALL:155:buffer too small
 EVP_R_CAMELLIA_KEY_SETUP_FAILED:157:camellia key setup failed
 EVP_R_CIPHER_PARAMETER_ERROR:122:cipher parameter error
@@ -2287,6 +2296,7 @@ EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM:118:unsupported private key algorithm
 EVP_R_UNSUPPORTED_SALT_TYPE:126:unsupported salt type
 EVP_R_WRAP_MODE_NOT_ALLOWED:170:wrap mode not allowed
 EVP_R_WRONG_FINAL_BLOCK_LENGTH:109:wrong final block length
+EVP_R_XTS_DUPLICATED_KEYS:183:xts duplicated keys
 KDF_R_INVALID_DIGEST:100:invalid digest
 KDF_R_MISSING_ITERATION_COUNT:109:missing iteration count
 KDF_R_MISSING_KEY:104:missing key
@@ -2527,6 +2537,7 @@ RSA_R_KEY_PRIME_NUM_INVALID:165:key prime num invalid
 RSA_R_KEY_SIZE_TOO_SMALL:120:key size too small
 RSA_R_LAST_OCTET_INVALID:134:last octet invalid
 RSA_R_MGF1_DIGEST_NOT_ALLOWED:152:mgf1 digest not allowed
+RSA_R_MISSING_PRIVATE_KEY:179:missing private key
 RSA_R_MODULUS_TOO_LARGE:105:modulus too large
 RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R:168:mp coefficient not inverse of r
 RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D:169:mp exponent not congruent to d
@@ -3003,6 +3014,7 @@ X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table
 X509_R_CRL_ALREADY_DELTA:127:crl already delta
 X509_R_CRL_VERIFY_FAILURE:131:crl verify failure
 X509_R_IDP_MISMATCH:128:idp mismatch
+X509_R_INVALID_ATTRIBUTES:138:invalid attributes
 X509_R_INVALID_DIRECTORY:113:invalid directory
 X509_R_INVALID_FIELD_NAME:119:invalid field name
 X509_R_INVALID_TRUST:123:invalid trust
index a046221..300db6c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -38,9 +38,9 @@
         of memory.
 
         BIO_f_reliable splits data stream into blocks. Each block is prefixed
-        with it's length and suffixed with it's digest. So you need only
+        with its length and suffixed with its digest. So you need only
         several Kbytes of memory to buffer single block before verifying
-        it's digest.
+        its digest.
 
         BIO_f_reliable goes further and adds several important capabilities:
 
index 68322e1..1db346f 100644 (file)
@@ -176,7 +176,7 @@ static void ctr64_inc(unsigned char *counter)
 # define HWAES_xts_decrypt aes_p8_xts_decrypt
 #endif
 
-#if     defined(AES_ASM) && !defined(I386_ONLY) &&      (  \
+#if     !defined(OPENSSL_NO_ASM) &&                     (  \
         ((defined(__i386)       || defined(__i386__)    || \
           defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
         defined(__x86_64)       || defined(__x86_64__)  || \
@@ -383,10 +383,25 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                               const unsigned char *iv, int enc)
 {
     EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
+
     if (!iv && !key)
         return 1;
 
     if (key) {
+        /* The key is two half length keys in reality */
+        const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2;
+
+        /*
+         * Verify that the two keys are different.
+         * 
+         * This addresses Rogaway's vulnerability.
+         * See comment in aes_xts_init_key() below.
+         */
+        if (enc && CRYPTO_memcmp(key, key + bytes, bytes) == 0) {
+            EVPerr(EVP_F_AESNI_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS);
+            return 0;
+        }
+
         /* key_len is two AES keys */
         if (enc) {
             aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
@@ -787,11 +802,26 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                                const unsigned char *iv, int enc)
 {
     EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
+
     if (!iv && !key)
         return 1;
 
     if (key) {
-        int bits = EVP_CIPHER_CTX_key_length(ctx) * 4;
+        /* The key is two half length keys in reality */
+        const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2;
+        const int bits = bytes * 8;
+
+        /*
+         * Verify that the two keys are different.
+         * 
+         * This addresses Rogaway's vulnerability.
+         * See comment in aes_xts_init_key() below.
+         */
+        if (enc && CRYPTO_memcmp(key, key + bytes, bytes) == 0) {
+            EVPerr(EVP_F_AES_T4_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS);
+            return 0;
+        }
+
         xctx->stream = NULL;
         /* key_len is two AES keys */
         if (enc) {
@@ -1578,7 +1608,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
 
     switch (type) {
     case EVP_CTRL_INIT:
-        ivlen = EVP_CIPHER_CTX_iv_length(c);
+        ivlen = EVP_CIPHER_iv_length(c->cipher);
         iv = EVP_CIPHER_CTX_iv_noconst(c);
         gctx->key_set = 0;
         gctx->iv_set = 0;
@@ -1589,6 +1619,10 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
         gctx->tls_aad_len = -1;
         return 1;
 
+    case EVP_CTRL_GET_IVLEN:
+        *(int *)ptr = gctx->ivlen;
+        return 1;
+
     case EVP_CTRL_AEAD_SET_IVLEN:
         if (arg <= 0)
             return 0;
@@ -2299,6 +2333,10 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
         cctx->aes.ccm.tls_aad_len = -1;
         return 1;
 
+    case EVP_CTRL_GET_IVLEN:
+        *(int *)ptr = 15 - cctx->aes.ccm.l;
+        return 1;
+
     case EVP_CTRL_AEAD_TLS1_AAD:
         if (arg != EVP_AEAD_TLS1_AAD_LEN)
             return 0;
@@ -2817,13 +2855,17 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
     case EVP_CTRL_INIT:
         gctx->key_set = 0;
         gctx->iv_set = 0;
-        gctx->ivlen = c->cipher->iv_len;
+        gctx->ivlen = EVP_CIPHER_iv_length(c->cipher);
         gctx->iv = c->iv;
         gctx->taglen = -1;
         gctx->iv_gen = 0;
         gctx->tls_aad_len = -1;
         return 1;
 
+    case EVP_CTRL_GET_IVLEN:
+        *(int *)ptr = gctx->ivlen;
+        return 1;
+
     case EVP_CTRL_AEAD_SET_IVLEN:
         if (arg <= 0)
             return 0;
@@ -3273,7 +3315,7 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 #define CUSTOM_FLAGS    (EVP_CIPH_FLAG_DEFAULT_ASN1 \
                 | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
                 | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
-                | EVP_CIPH_CUSTOM_COPY)
+                | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_CUSTOM_IV_LENGTH)
 
 BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM,
                     EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
@@ -3284,10 +3326,12 @@ BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM,
 
 static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
 {
-    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,c);
+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX, c);
+
     if (type == EVP_CTRL_COPY) {
         EVP_CIPHER_CTX *out = ptr;
         EVP_AES_XTS_CTX *xctx_out = EVP_C_DATA(EVP_AES_XTS_CTX,out);
+
         if (xctx->xts.key1) {
             if (xctx->xts.key1 != &xctx->ks1)
                 return 0;
@@ -3311,11 +3355,36 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                             const unsigned char *iv, int enc)
 {
     EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
+
     if (!iv && !key)
         return 1;
 
     if (key)
         do {
+            /* The key is two half length keys in reality */
+            const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2;
+
+            /*
+             * Verify that the two keys are different.
+             *
+             * This addresses the vulnerability described in Rogaway's
+             * September 2004 paper:
+             *
+             *      "Efficient Instantiations of Tweakable Blockciphers and
+             *       Refinements to Modes OCB and PMAC".
+             *      (http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf)
+             *
+             * FIPS 140-2 IG A.9 XTS-AES Key Generation Requirements states
+             * that:
+             *      "The check for Key_1 != Key_2 shall be done at any place
+             *       BEFORE using the keys in the XTS-AES algorithm to process
+             *       data with them."
+             */
+            if (enc && CRYPTO_memcmp(key, key + bytes, bytes) == 0) {
+                EVPerr(EVP_F_AES_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS);
+                return 0;
+            }
+
 #ifdef AES_XTS_ASM
             xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
 #else
@@ -3448,7 +3517,9 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
         cctx->len_set = 0;
         cctx->tls_aad_len = -1;
         return 1;
-
+    case EVP_CTRL_GET_IVLEN:
+        *(int *)ptr = 15 - cctx->L;
+        return 1;
     case EVP_CTRL_AEAD_TLS1_AAD:
         /* Save the AAD for later use */
         if (arg != EVP_AEAD_TLS1_AAD_LEN)
@@ -3897,13 +3968,17 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
     case EVP_CTRL_INIT:
         octx->key_set = 0;
         octx->iv_set = 0;
-        octx->ivlen = EVP_CIPHER_CTX_iv_length(c);
+        octx->ivlen = EVP_CIPHER_iv_length(c->cipher);
         octx->iv = EVP_CIPHER_CTX_iv_noconst(c);
         octx->taglen = 16;
         octx->data_buf_len = 0;
         octx->aad_buf_len = 0;
         return 1;
 
+    case EVP_CTRL_GET_IVLEN:
+        *(int *)ptr = octx->ivlen;
+        return 1;
+
     case EVP_CTRL_AEAD_SET_IVLEN:
         /* IV len must be 1 to 15 */
         if (arg <= 0 || arg > 15)
index 100573f..fcaceb3 100644 (file)
@@ -252,7 +252,7 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
     case EVP_CTRL_INIT:
         gctx->key_set = 0;
         gctx->iv_set = 0;
-        gctx->ivlen = EVP_CIPHER_CTX_iv_length(c);
+        gctx->ivlen = EVP_CIPHER_iv_length(c->cipher);
         gctx->iv = EVP_CIPHER_CTX_iv_noconst(c);
         gctx->taglen = -1;
         gctx->iv_gen = 0;
@@ -274,6 +274,10 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
         gctx->ivlen = arg;
         return 1;
 
+    case EVP_CTRL_GET_IVLEN:
+        *(int *)ptr = gctx->ivlen;
+        return 1;
+
     case EVP_CTRL_AEAD_SET_TAG:
         if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_encrypting(c))
             return 0;
@@ -573,6 +577,10 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
         memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg);
         return 1;
 
+    case EVP_CTRL_GET_IVLEN:
+        *(int *)ptr = 15 - cctx->L;
+        return 1;
+
     case EVP_CTRL_AEAD_SET_IVLEN:
         arg = 15 - arg;
         /* fall thru */
@@ -742,7 +750,8 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 #define ARIA_AUTH_FLAGS  (EVP_CIPH_FLAG_DEFAULT_ASN1 \
                           | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
                           | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
-                          | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER)
+                          | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER \
+                          | EVP_CIPH_CUSTOM_IV_LENGTH)
 
 #define BLOCK_CIPHER_aead(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
 static const EVP_CIPHER aria_##keylen##_##mode = { \
index 600365d..435a38d 100644 (file)
@@ -534,6 +534,10 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
         }
         return 1;
 
+    case EVP_CTRL_GET_IVLEN:
+        *(int *)ptr = actx->nonce_len;
+        return 1;
+
     case EVP_CTRL_AEAD_SET_IVLEN:
         if (arg <= 0 || arg > CHACHA20_POLY1305_MAX_IVLEN)
             return 0;
@@ -613,7 +617,8 @@ static EVP_CIPHER chacha20_poly1305 = {
     12,                 /* iv_len, 96-bit nonce in the context */
     EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV |
     EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
-    EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER,
+    EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER |
+    EVP_CIPH_CUSTOM_IV_LENGTH,
     chacha20_poly1305_init_key,
     chacha20_poly1305_cipher,
     chacha20_poly1305_cleanup,
index a2f26d8..dc5589b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -66,6 +66,10 @@ static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
 static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                                const unsigned char *iv, int enc)
 {
+    if (EVP_CIPHER_CTX_key_length(ctx) > 255) {
+        EVPerr(EVP_F_R_32_12_16_INIT_KEY, EVP_R_BAD_KEY_LENGTH);
+        return 0;
+    }
     RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
                    key, data(ctx)->rounds);
     return 1;
index 60df27c..84bd3c2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 
 static const ERR_STRING_DATA EVP_str_functs[] = {
     {ERR_PACK(ERR_LIB_EVP, EVP_F_AESNI_INIT_KEY, 0), "aesni_init_key"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_AESNI_XTS_INIT_KEY, 0), "aesni_xts_init_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_GCM_CTRL, 0), "aes_gcm_ctrl"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_INIT_KEY, 0), "aes_init_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_OCB_CIPHER, 0), "aes_ocb_cipher"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_T4_INIT_KEY, 0), "aes_t4_init_key"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_T4_XTS_INIT_KEY, 0),
+     "aes_t4_xts_init_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_WRAP_CIPHER, 0), "aes_wrap_cipher"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_XTS_INIT_KEY, 0), "aes_xts_init_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_ALG_MODULE_INIT, 0), "alg_module_init"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_CCM_INIT_KEY, 0), "aria_ccm_init_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_CTRL, 0), "aria_gcm_ctrl"},
@@ -149,6 +153,8 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
     {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_R_32_12_16_INIT_KEY, 0),
+     "r_32_12_16_init_key"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_UPDATE, 0), "update"},
     {0, NULL}
@@ -160,6 +166,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ARIA_KEY_SETUP_FAILED),
     "aria key setup failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT), "bad decrypt"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_KEY_LENGTH), "bad key length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED),
     "camellia key setup failed"},
@@ -266,6 +273,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
     "wrap mode not allowed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_FINAL_BLOCK_LENGTH),
     "wrong final block length"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DUPLICATED_KEYS),
+    "xts duplicated keys"},
     {0, NULL}
 };
 
index 1b3c984..4935c2a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -242,6 +242,13 @@ int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
 
 int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
 {
+    int i, rv;
+
+    if ((EVP_CIPHER_flags(ctx->cipher) & EVP_CIPH_CUSTOM_IV_LENGTH) != 0) {
+        rv = EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)ctx, EVP_CTRL_GET_IVLEN,
+                                 0, &i);
+        return (rv == 1) ? i : -1;
+    }
     return ctx->cipher->iv_len;
 }
 
index 31379c0..01cf57d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -108,6 +108,9 @@ static int sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
     size_t bsz = ctx->block_size;
     size_t num = ctx->num;
 
+    if (ctx->md_size == 0)
+        return 1;
+
     /*
      * Pad the data with 10*1. Note that |num| can be |bsz - 1|
      * in which case both byte operations below are performed on
index a35b12b..9f3a583 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -57,6 +57,8 @@ int ossl_ctype_check(int c, unsigned int mask);
 int ossl_tolower(int c);
 int ossl_toupper(int c);
 
+int ascii_isdigit(const char inchar);
+
 # define ossl_isalnum(c)        (ossl_ctype_check((c), CTYPE_MASK_alnum))
 # define ossl_isalpha(c)        (ossl_ctype_check((c), CTYPE_MASK_alpha))
 # ifdef CHARSET_EBCDIC
index 888cab1..10347ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -26,7 +26,6 @@ typedef struct rand_pool_st RAND_POOL;
 void rand_cleanup_int(void);
 void rand_drbg_cleanup_int(void);
 void drbg_delete_thread_state(void);
-void rand_fork(void);
 
 /* Hardware-based seeding functions. */
 size_t rand_acquire_entropy_from_tsc(RAND_POOL *pool);
@@ -52,7 +51,8 @@ void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out);
 /*
  * RAND_POOL functions
  */
-RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len);
+RAND_POOL *rand_pool_new(int entropy_requested, int secure,
+                         size_t min_len, size_t max_len);
 RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len,
                             size_t entropy);
 void rand_pool_free(RAND_POOL *pool);
index a4db1b7..09edfab 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_SM2ERR_H
 # define HEADER_SM2ERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_SM2
index 62626a7..9fc0e8e 100644 (file)
@@ -40,7 +40,7 @@ static int stopped = 0;
  * destructor for threads terminating before libcrypto is initialized or
  * after it's de-initialized. Access to the key doesn't have to be
  * serialized for the said threads, because they didn't use libcrypto
- * and it doesn't matter if they pick "impossible" or derefernce real
+ * and it doesn't matter if they pick "impossible" or dereference real
  * key value and pull NULL past initialization in the first thread that
  * intends to use libcrypto.
  */
@@ -847,6 +847,5 @@ void OPENSSL_fork_parent(void)
 
 void OPENSSL_fork_child(void)
 {
-    rand_fork();
 }
 #endif
index 8d9f933..485d4c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 
 /*
  * A hashing implementation that appears to be based on the linear hashing
- * alogrithm:
+ * algorithm:
  * https://en.wikipedia.org/wiki/Linear_hashing
  *
  * Litwin, Witold (1980), "Linear hashing: A new tool for file and table
  * addressing", Proc. 6th Conference on Very Large Databases: 212-223
- * http://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf
+ * https://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf
  *
- * From the wikipedia article "Linear hashing is used in the BDB Berkeley
+ * From the Wikipedia article "Linear hashing is used in the BDB Berkeley
  * database system, which in turn is used by many software systems such as
  * OpenLDAP, using a C implementation derived from the CACM article and first
  * published on the Usenet in 1988 by Esmond Pitt."
index 1dbd70d..9ad7a89 100644 (file)
@@ -231,7 +231,7 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen)
      * buf is left unused.
      */
     err = strerror_r(errnum, buf, buflen);
-    if (err == NULL)
+    if (err == NULL || buflen == 0)
         return 0;
     /*
      * If err is statically allocated, err != buf and we need to copy the data.
index e39c243..2bbee4a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -274,6 +274,9 @@ static EVP_PKEY *b2i_dss(const unsigned char **in,
         if (!read_lebn(&p, 20, &priv_key))
             goto memerr;
 
+        /* Set constant time flag before public key calculation */
+        BN_set_flags(priv_key, BN_FLG_CONSTTIME);
+
         /* Calculate public key */
         pub_key = BN_new();
         if (pub_key == NULL)
index ee08e60..f63fbc5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -137,7 +137,8 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
 }
 
 static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
-                               PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
+                               PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey,
+                               size_t fixlen)
 {
     EVP_PKEY_CTX *pctx = NULL;
     unsigned char *ek = NULL;
@@ -170,7 +171,9 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
     }
 
     if (EVP_PKEY_decrypt(pctx, ek, &eklen,
-                         ri->enc_key->data, ri->enc_key->length) <= 0) {
+                         ri->enc_key->data, ri->enc_key->length) <= 0
+            || eklen == 0
+            || (fixlen != 0 && eklen != fixlen)) {
         ret = 0;
         PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
         goto err;
@@ -499,13 +502,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
             for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
                 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
 
-                if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
+                if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
+                        EVP_CIPHER_key_length(evp_cipher)) < 0)
                     goto err;
                 ERR_clear_error();
             }
         } else {
             /* Only exit on fatal errors, not decrypt failure */
-            if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
+            if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0)
                 goto err;
             ERR_clear_error();
         }
index abbe0a8..12bb627 100644 (file)
@@ -197,7 +197,7 @@ static RAND_DRBG *rand_drbg_new(int secure,
     }
 
     drbg->secure = secure && CRYPTO_secure_allocated(drbg);
-    drbg->fork_count = rand_fork_count;
+    drbg->fork_id = openssl_get_fork_id();
     drbg->parent = parent;
 
     if (parent == NULL) {
@@ -318,7 +318,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
     /*
      * NIST SP800-90Ar1 section 9.1 says you can combine getting the entropy
      * and nonce in 1 call by increasing the entropy with 50% and increasing
-     * the minimum length to accomadate the length of the nonce.
+     * the minimum length to accommodate the length of the nonce.
      * We do this in case a nonce is require and get_nonce is NULL.
      */
     if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) {
@@ -578,6 +578,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
                        int prediction_resistance,
                        const unsigned char *adin, size_t adinlen)
 {
+    int fork_id;
     int reseed_required = 0;
 
     if (drbg->state != DRBG_READY) {
@@ -603,8 +604,10 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
         return 0;
     }
 
-    if (drbg->fork_count != rand_fork_count) {
-        drbg->fork_count = rand_fork_count;
+    fork_id = openssl_get_fork_id();
+
+    if (drbg->fork_id != fork_id) {
+        drbg->fork_id = fork_id;
         reseed_required = 1;
     }
 
@@ -664,7 +667,7 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
     if (drbg->adin_pool == NULL) {
         if (drbg->type == 0)
             goto err;
-        drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen);
+        drbg->adin_pool = rand_pool_new(0, 0, 0, drbg->max_adinlen);
         if (drbg->adin_pool == NULL)
             goto err;
     }
index 6a87045..ae4d855 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -47,6 +47,7 @@ static const ERR_STRING_DATA RAND_str_functs[] = {
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ATTACH, 0), "rand_pool_attach"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_BYTES_NEEDED, 0),
      "rand_pool_bytes_needed"},
+    {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_GROW, 0), "rand_pool_grow"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_NEW, 0), "rand_pool_new"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_WRITE_FILE, 0), "RAND_write_file"},
     {0, NULL}
index c3e9804..306c59f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -45,7 +45,6 @@
 # define DRBG_MAX_LENGTH                         INT32_MAX
 
 
-
 /*
  * Maximum allocation size for RANDOM_POOL buffers
  *
  *                                1.5 * (RAND_DRBG_STRENGTH / 8))
  */
 
+/*
+ * Initial allocation minimum.
+ *
+ * There is a distinction between the secure and normal allocation minimums.
+ * Ideally, the secure allocation size should be a power of two.  The normal
+ * allocation size doesn't have any such restriction.
+ *
+ * The secure value is based on 128 bits of secure material, which is 16 bytes.
+ * Typically, the DRBGs will set a minimum larger than this so optimal
+ * allocation ought to take place (for full quality seed material).
+ *
+ * The normal value has been chosed by noticing that the rand_drbg_get_nonce
+ * function is usually the largest of the built in allocation (twenty four
+ * bytes and then appending another sixteen bytes).  This means the buffer ends
+ * with 40 bytes.  The value of forty eight is comfortably above this which
+ * allows some slack in the platform specific values used.
+ */
+# define RAND_POOL_MIN_ALLOCATION(secure) ((secure) ? 16 : 48)
 
 /* DRBG status values */
 typedef enum drbg_status_e {
@@ -150,9 +167,11 @@ struct rand_pool_st {
     size_t len; /* current number of random bytes contained in the pool */
 
     int attached;  /* true pool was attached to existing buffer */
+    int secure;    /* 1: allocated on the secure heap, 0: otherwise */
 
     size_t min_len; /* minimum number of random bytes requested */
     size_t max_len; /* maximum number of random bytes (allocated buffer size) */
+    size_t alloc_len; /* current number of bytes allocated */
     size_t entropy; /* current entropy count in bits */
     size_t entropy_requested; /* requested entropy count in bits */
 };
@@ -167,12 +186,12 @@ struct rand_drbg_st {
     int secure; /* 1: allocated on the secure heap, 0: otherwise */
     int type; /* the nid of the underlying algorithm */
     /*
-     * Stores the value of the rand_fork_count global as of when we last
-     * reseeded.  The DRBG reseeds automatically whenever drbg->fork_count !=
-     * rand_fork_count.  Used to provide fork-safety and reseed this DRBG in
-     * the child process.
+     * Stores the return value of openssl_get_fork_id() as of when we last
+     * reseeded.  The DRBG reseeds automatically whenever drbg->fork_id !=
+     * openssl_get_fork_id().  Used to provide fork-safety and reseed this
+     * DRBG in the child process.
      */
-    int fork_count;
+    int fork_id;
     unsigned short flags; /* various external flags */
 
     /*
@@ -264,19 +283,6 @@ struct rand_drbg_st {
 /* The global RAND method, and the global buffer and DRBG instance. */
 extern RAND_METHOD rand_meth;
 
-/*
- * A "generation count" of forks.  Incremented in the child process after a
- * fork.  Since rand_fork_count is increment-only, and only ever written to in
- * the child process of the fork, which is guaranteed to be single-threaded, no
- * locking is needed for normal (read) accesses; the rest of pthread fork
- * processing is assumed to introduce the necessary memory barriers.  Sibling
- * children of a given parent will produce duplicate values, but this is not
- * problematic because the reseeding process pulls input from the system CSPRNG
- * and/or other global sources, so the siblings will end up generating
- * different output streams.
- */
-extern int rand_fork_count;
-
 /* DRBG helpers */
 int rand_drbg_restart(RAND_DRBG *drbg,
                       const unsigned char *buffer, size_t len, size_t entropy);
index 108b4f5..91b2652 100644 (file)
@@ -26,8 +26,6 @@ static CRYPTO_RWLOCK *rand_meth_lock;
 static const RAND_METHOD *default_RAND_meth;
 static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT;
 
-int rand_fork_count;
-
 static CRYPTO_RWLOCK *rand_nonce_lock;
 static int rand_nonce_count;
 
@@ -150,7 +148,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
         pool = drbg->seed_pool;
         pool->entropy_requested = entropy;
     } else {
-        pool = rand_pool_new(entropy, min_len, max_len);
+        pool = rand_pool_new(entropy, drbg->secure, min_len, max_len);
         if (pool == NULL)
             return 0;
     }
@@ -163,7 +161,9 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
             size_t bytes = 0;
 
             /*
-             * Get random from parent, include our state as additional input.
+             * Get random data from parent. Include our address as additional input,
+             * in order to provide some additional distinction between different
+             * DRBG child instances.
              * Our lock is already held, but we need to lock our parent before
              * generating bits from it. (Note: taking the lock will be a no-op
              * if locking if drbg->parent->lock == NULL.)
@@ -172,7 +172,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
             if (RAND_DRBG_generate(drbg->parent,
                                    buffer, bytes_needed,
                                    prediction_resistance,
-                                   NULL, 0) != 0)
+                                   (unsigned char *)&drbg, sizeof(drbg)) != 0)
                 bytes = bytes_needed;
             drbg->reseed_next_counter
                 = tsan_load(&drbg->parent->reseed_prop_counter);
@@ -216,8 +216,12 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
 void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
                                unsigned char *out, size_t outlen)
 {
-    if (drbg->seed_pool == NULL)
-        OPENSSL_secure_clear_free(out, outlen);
+    if (drbg->seed_pool == NULL) {
+        if (drbg->secure)
+            OPENSSL_secure_clear_free(out, outlen);
+        else
+            OPENSSL_clear_free(out, outlen);
+    }
 }
 
 
@@ -235,9 +239,10 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
     struct {
         void * instance;
         int count;
-    } data = { NULL, 0 };
+    } data;
 
-    pool = rand_pool_new(0, min_len, max_len);
+    memset(&data, 0, sizeof(data));
+    pool = rand_pool_new(0, 0, min_len, max_len);
     if (pool == NULL)
         return 0;
 
@@ -266,7 +271,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
 void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
                              unsigned char *out, size_t outlen)
 {
-    OPENSSL_secure_clear_free(out, outlen);
+    OPENSSL_clear_free(out, outlen);
 }
 
 /*
@@ -298,11 +303,6 @@ void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out)
     rand_pool_reattach(pool, out);
 }
 
-void rand_fork(void)
-{
-    rand_fork_count++;
-}
-
 DEFINE_RUN_ONCE_STATIC(do_rand_init)
 {
 #ifndef OPENSSL_NO_ENGINE
@@ -362,7 +362,7 @@ void rand_cleanup_int(void)
 }
 
 /*
- * RAND_close_seed_files() ensures that any seed file decriptors are
+ * RAND_close_seed_files() ensures that any seed file descriptors are
  * closed after use.
  */
 void RAND_keep_random_devices_open(int keep)
@@ -401,7 +401,7 @@ int RAND_poll(void)
 
     } else {
         /* fill random pool and seed the current legacy RNG */
-        pool = rand_pool_new(RAND_DRBG_STRENGTH,
+        pool = rand_pool_new(RAND_DRBG_STRENGTH, 1,
                              (RAND_DRBG_STRENGTH + 7) / 8,
                              RAND_POOL_MAX_LENGTH);
         if (pool == NULL)
@@ -428,9 +428,11 @@ err:
  * Allocate memory and initialize a new random pool
  */
 
-RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len)
+RAND_POOL *rand_pool_new(int entropy_requested, int secure,
+                         size_t min_len, size_t max_len)
 {
     RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool));
+    size_t min_alloc_size = RAND_POOL_MIN_ALLOCATION(secure);
 
     if (pool == NULL) {
         RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
@@ -440,14 +442,22 @@ RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len)
     pool->min_len = min_len;
     pool->max_len = (max_len > RAND_POOL_MAX_LENGTH) ?
         RAND_POOL_MAX_LENGTH : max_len;
+    pool->alloc_len = min_len < min_alloc_size ? min_alloc_size : min_len;
+    if (pool->alloc_len > pool->max_len)
+        pool->alloc_len = pool->max_len;
+
+    if (secure)
+        pool->buffer = OPENSSL_secure_zalloc(pool->alloc_len);
+    else
+        pool->buffer = OPENSSL_zalloc(pool->alloc_len);
 
-    pool->buffer = OPENSSL_secure_zalloc(pool->max_len);
     if (pool->buffer == NULL) {
         RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     pool->entropy_requested = entropy_requested;
+    pool->secure = secure;
 
     return pool;
 
@@ -482,7 +492,7 @@ RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len,
 
     pool->attached = 1;
 
-    pool->min_len = pool->max_len = pool->len;
+    pool->min_len = pool->max_len = pool->alloc_len = pool->len;
     pool->entropy = entropy;
 
     return pool;
@@ -502,8 +512,13 @@ void rand_pool_free(RAND_POOL *pool)
      * to rand_pool_attach() as `const unsigned char*`.
      * (see corresponding comment in rand_pool_attach()).
      */
-    if (!pool->attached)
-        OPENSSL_secure_clear_free(pool->buffer, pool->max_len);
+    if (!pool->attached) {
+        if (pool->secure)
+            OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len);
+        else
+            OPENSSL_clear_free(pool->buffer, pool->alloc_len);
+    }
+
     OPENSSL_free(pool);
 }
 
@@ -596,6 +611,42 @@ size_t rand_pool_entropy_needed(RAND_POOL *pool)
     return 0;
 }
 
+/* Increase the allocation size -- not usable for an attached pool */
+static int rand_pool_grow(RAND_POOL *pool, size_t len)
+{
+    if (len > pool->alloc_len - pool->len) {
+        unsigned char *p;
+        const size_t limit = pool->max_len / 2;
+        size_t newlen = pool->alloc_len;
+
+        if (pool->attached || len > pool->max_len - pool->len) {
+            RANDerr(RAND_F_RAND_POOL_GROW, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+
+        do
+            newlen = newlen < limit ? newlen * 2 : pool->max_len;
+        while (len > newlen - pool->len);
+
+        if (pool->secure)
+            p = OPENSSL_secure_zalloc(newlen);
+        else
+            p = OPENSSL_zalloc(newlen);
+        if (p == NULL) {
+            RANDerr(RAND_F_RAND_POOL_GROW, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        memcpy(p, pool->buffer, pool->len);
+        if (pool->secure)
+            OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len);
+        else
+            OPENSSL_clear_free(pool->buffer, pool->alloc_len);
+        pool->buffer = p;
+        pool->alloc_len = newlen;
+    }
+    return 1;
+}
+
 /*
  * Returns the number of bytes needed to fill the pool, assuming
  * the input has 1 / |entropy_factor| entropy bits per data bit.
@@ -625,6 +676,24 @@ size_t rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor)
         /* to meet the min_len requirement */
         bytes_needed = pool->min_len - pool->len;
 
+    /*
+     * Make sure the buffer is large enough for the requested amount
+     * of data. This guarantees that existing code patterns where
+     * rand_pool_add_begin, rand_pool_add_end or rand_pool_add
+     * are used to collect entropy data without any error handling
+     * whatsoever, continue to be valid.
+     * Furthermore if the allocation here fails once, make sure that
+     * we don't fall back to a less secure or even blocking random source,
+     * as that could happen by the existing code patterns.
+     * This is not a concern for additional data, therefore that
+     * is not needed if rand_pool_grow fails in other places.
+     */
+    if (!rand_pool_grow(pool, bytes_needed)) {
+        /* persistent error for this pool */
+        pool->max_len = pool->len = 0;
+        return 0;
+    }
+
     return bytes_needed;
 }
 
@@ -657,6 +726,27 @@ int rand_pool_add(RAND_POOL *pool,
     }
 
     if (len > 0) {
+        /*
+         * This is to protect us from accidentally passing the buffer
+         * returned from rand_pool_add_begin.
+         * The check for alloc_len makes sure we do not compare the
+         * address of the end of the allocated memory to something
+         * different, since that comparison would have an
+         * indeterminate result.
+         */
+        if (pool->alloc_len > pool->len && pool->buffer + pool->len == buffer) {
+            RANDerr(RAND_F_RAND_POOL_ADD, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+        /*
+         * We have that only for cases when a pool is used to collect
+         * additional data.
+         * For entropy data, as long as the allocation request stays within
+         * the limits given by rand_pool_bytes_needed this rand_pool_grow
+         * below is guaranteed to succeed, thus no allocation happens.
+         */
+        if (!rand_pool_grow(pool, len))
+            return 0;
         memcpy(pool->buffer + pool->len, buffer, len);
         pool->len += len;
         pool->entropy += entropy;
@@ -692,6 +782,18 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
         return NULL;
     }
 
+    /*
+     * As long as the allocation request stays within the limits given
+     * by rand_pool_bytes_needed this rand_pool_grow below is guaranteed
+     * to succeed, thus no allocation happens.
+     * We have that only for cases when a pool is used to collect
+     * additional data. Then the buffer might need to grow here,
+     * and of course the caller is responsible to check the return
+     * value of this function.
+     */
+    if (!rand_pool_grow(pool, len))
+        return NULL;
+
     return pool->buffer + pool->len;
 }
 
@@ -706,7 +808,7 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
  */
 int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy)
 {
-    if (len > pool->max_len - pool->len) {
+    if (len > pool->alloc_len - pool->len) {
         RANDerr(RAND_F_RAND_POOL_ADD_END, RAND_R_RANDOM_POOL_OVERFLOW);
         return 0;
     }
index 4710dbb..69efcde 100644 (file)
 #include <stdio.h>
 #include "internal/cryptlib.h"
 #include <openssl/rand.h>
+#include <openssl/crypto.h>
 #include "rand_lcl.h"
 #include "internal/rand_int.h"
 #include <stdio.h>
 #include "internal/dso.h"
-#if defined(__linux)
-# include <asm/unistd.h>
+#ifdef __linux
+# include <sys/syscall.h>
+# ifdef DEVRANDOM_WAIT
+#  include <sys/shm.h>
+#  include <sys/utsname.h>
+# endif
 #endif
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) && !defined(OPENSSL_SYS_UEFI)
 # include <sys/types.h>
 # include <sys/sysctl.h>
 # include <sys/param.h>
@@ -275,6 +280,17 @@ static ssize_t sysctl_random(char *buf, size_t buflen)
 #  endif
 
 #  if defined(OPENSSL_RAND_SEED_GETRANDOM)
+
+#   if defined(__linux) && !defined(__NR_getrandom)
+#    if defined(__arm__) && defined(__NR_SYSCALL_BASE)
+#     define __NR_getrandom    (__NR_SYSCALL_BASE+384)
+#    elif defined(__i386__)
+#     define __NR_getrandom    355
+#    elif defined(__x86_64__) && !defined(__ILP32__)
+#     define __NR_getrandom    318
+#    endif
+#   endif
+
 /*
  * syscall_random(): Try to get random data using a system call
  * returns the number of bytes returned in buf, or < 0 on error.
@@ -346,6 +362,91 @@ static struct random_device {
 } random_devices[OSSL_NELEM(random_device_paths)];
 static int keep_random_devices_open = 1;
 
+#   if defined(__linux) && defined(DEVRANDOM_WAIT)
+static void *shm_addr;
+
+static void cleanup_shm(void)
+{
+    shmdt(shm_addr);
+}
+
+/*
+ * Ensure that the system randomness source has been adequately seeded.
+ * This is done by having the first start of libcrypto, wait until the device
+ * /dev/random becomes able to supply a byte of entropy.  Subsequent starts
+ * of the library and later reseedings do not need to do this.
+ */
+static int wait_random_seeded(void)
+{
+    static int seeded = OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID < 0;
+    static const int kernel_version[] = { DEVRANDOM_SAFE_KERNEL };
+    int kernel[2];
+    int shm_id, fd, r;
+    char c, *p;
+    struct utsname un;
+    fd_set fds;
+
+    if (!seeded) {
+        /* See if anything has created the global seeded indication */
+        if ((shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1, 0)) == -1) {
+            /*
+             * Check the kernel's version and fail if it is too recent.
+             *
+             * Linux kernels from 4.8 onwards do not guarantee that
+             * /dev/urandom is properly seeded when /dev/random becomes
+             * readable.  However, such kernels support the getentropy(2)
+             * system call and this should always succeed which renders
+             * this alternative but essentially identical source moot.
+             */
+            if (uname(&un) == 0) {
+                kernel[0] = atoi(un.release);
+                p = strchr(un.release, '.');
+                kernel[1] = p == NULL ? 0 : atoi(p + 1);
+                if (kernel[0] > kernel_version[0]
+                    || (kernel[0] == kernel_version[0]
+                        && kernel[1] >= kernel_version[1])) {
+                    return 0;
+                }
+            }
+            /* Open /dev/random and wait for it to be readable */
+            if ((fd = open(DEVRANDOM_WAIT, O_RDONLY)) != -1) {
+                if (DEVRANDM_WAIT_USE_SELECT && fd < FD_SETSIZE) {
+                    FD_ZERO(&fds);
+                    FD_SET(fd, &fds);
+                    while ((r = select(fd + 1, &fds, NULL, NULL, NULL)) < 0
+                           && errno == EINTR);
+                } else {
+                    while ((r = read(fd, &c, 1)) < 0 && errno == EINTR);
+                }
+                close(fd);
+                if (r == 1) {
+                    seeded = 1;
+                    /* Create the shared memory indicator */
+                    shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1,
+                                    IPC_CREAT | S_IRUSR | S_IRGRP | S_IROTH);
+                }
+            }
+        }
+        if (shm_id != -1) {
+            seeded = 1;
+            /*
+             * Map the shared memory to prevent its premature destruction.
+             * If this call fails, it isn't a big problem.
+             */
+            shm_addr = shmat(shm_id, NULL, SHM_RDONLY);
+            if (shm_addr != (void *)-1)
+                OPENSSL_atexit(&cleanup_shm);
+        }
+    }
+    return seeded;
+}
+#   else /* defined __linux */
+static int wait_random_seeded(void)
+{
+    return 1;
+}
+#   endif
+
 /*
  * Verify that the file descriptor associated with the random source is
  * still valid. The rationale for doing this is the fact that it is not
@@ -472,12 +573,12 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
 #  if defined(OPENSSL_RAND_SEED_NONE)
     return rand_pool_entropy_available(pool);
 #  else
-    size_t bytes_needed;
-    size_t entropy_available = 0;
-    unsigned char *buffer;
+    size_t entropy_available;
 
 #   if defined(OPENSSL_RAND_SEED_GETRANDOM)
     {
+        size_t bytes_needed;
+        unsigned char *buffer;
         ssize_t bytes;
         /* Maximum allowed number of consecutive unsuccessful attempts */
         int attempts = 3;
@@ -507,36 +608,16 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
 #   endif
 
 #   if defined(OPENSSL_RAND_SEED_DEVRANDOM)
-    bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
-    {
+    if (wait_random_seeded()) {
+        size_t bytes_needed;
+        unsigned char *buffer;
         size_t i;
-#ifdef DEVRANDOM_WAIT
-        static int wait_done = 0;
 
-        /*
-         * On some implementations reading from /dev/urandom is possible
-         * before it is initialized. Therefore we wait for /dev/random
-         * to be readable to make sure /dev/urandom is initialized.
-         */
-        if (!wait_done && bytes_needed > 0) {
-             int f = open(DEVRANDOM_WAIT, O_RDONLY);
-
-             if (f >= 0) {
-                 fd_set fds;
-
-                 FD_ZERO(&fds);
-                 FD_SET(f, &fds);
-                 while (select(f+1, &fds, NULL, NULL, NULL) < 0
-                        && errno == EINTR);
-                 close(f);
-             }
-             wait_done = 1;
-        }
-#endif
-
-        for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths); i++) {
+        bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
+        for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths);
+             i++) {
             ssize_t bytes = 0;
-            /* Maximum allowed number of consecutive unsuccessful attempts */
+            /* Maximum number of consecutive unsuccessful attempts */
             int attempts = 3;
             const int fd = get_random_device(i);
 
@@ -550,7 +631,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
                 if (bytes > 0) {
                     rand_pool_add_end(pool, bytes, 8 * bytes);
                     bytes_needed -= bytes;
-                    attempts = 3; /* reset counter after successful attempt */
+                    attempts = 3; /* reset counter on successful attempt */
                 } else if (bytes < 0 && errno != EINTR) {
                     break;
                 }
@@ -558,7 +639,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
             if (bytes < 0 || !keep_random_devices_open)
                 close_random_device(i);
 
-            bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
+            bytes_needed = rand_pool_bytes_needed(pool, 1);
         }
         entropy_available = rand_pool_entropy_available(pool);
         if (entropy_available > 0)
@@ -579,26 +660,29 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
 #   endif
 
 #   if defined(OPENSSL_RAND_SEED_EGD)
-    bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
-    if (bytes_needed > 0) {
+    {
         static const char *paths[] = { DEVRANDOM_EGD, NULL };
+        size_t bytes_needed;
+        unsigned char *buffer;
         int i;
 
-        for (i = 0; paths[i] != NULL; i++) {
+        bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
+        for (i = 0; bytes_needed > 0 && paths[i] != NULL; i++) {
+            size_t bytes = 0;
+            int num;
+
             buffer = rand_pool_add_begin(pool, bytes_needed);
-            if (buffer != NULL) {
-                size_t bytes = 0;
-                int num = RAND_query_egd_bytes(paths[i],
-                                               buffer, (int)bytes_needed);
-                if (num == (int)bytes_needed)
-                    bytes = bytes_needed;
+            num = RAND_query_egd_bytes(paths[i],
+                                       buffer, (int)bytes_needed);
+            if (num == (int)bytes_needed)
+                bytes = bytes_needed;
 
-                rand_pool_add_end(pool, bytes, 8 * bytes);
-                entropy_available = rand_pool_entropy_available(pool);
-            }
-            if (entropy_available > 0)
-                return entropy_available;
+            rand_pool_add_end(pool, bytes, 8 * bytes);
+            bytes_needed = rand_pool_bytes_needed(pool, 1);
         }
+        entropy_available = rand_pool_entropy_available(pool);
+        if (entropy_available > 0)
+            return entropy_available;
     }
 #   endif
 
@@ -632,15 +716,18 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
 int rand_pool_add_additional_data(RAND_POOL *pool)
 {
     struct {
+        int fork_id;
         CRYPTO_THREAD_ID tid;
         uint64_t time;
     } data = { 0 };
 
     /*
      * Add some noise from the thread id and a high resolution timer.
+     * The fork_id adds some extra fork-safety.
      * The thread id adds a little randomness if the drbg is accessed
      * concurrently (which is the case for the <master> drbg).
      */
+    data.fork_id = openssl_get_fork_id();
     data.tid = CRYPTO_THREAD_get_current_id();
     data.time = get_timer_bits();
 
index 56d79e7..a9c5751 100644 (file)
@@ -19,7 +19,8 @@
 
 # include <windows.h>
 /* On Windows Vista or higher use BCrypt instead of the legacy CryptoAPI */
-# if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
+# if defined(_MSC_VER) && _MSC_VER > 1500 /* 1500 = Visual Studio 2008 */ \
+     && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
 #  define USE_BCRYPTGENRANDOM
 # endif
 
index ab5f615..9dcb85d 100644 (file)
@@ -458,6 +458,9 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
 static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
 {
     X509_ALGOR *alg = NULL;
+    const EVP_MD *md;
+    const EVP_MD *mgf1md;
+    int min_saltlen;
 
     switch (op) {
 
@@ -497,6 +500,16 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
 #endif
 
     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+        if (pkey->pkey.rsa->pss != NULL) {
+            if (!rsa_pss_get_param(pkey->pkey.rsa->pss, &md, &mgf1md,
+                                   &min_saltlen)) {
+                RSAerr(0, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
+            *(int *)arg2 = EVP_MD_type(md);
+            /* Return of 2 indicates this MD is mandatory */
+            return 2;
+        }
         *(int *)arg2 = NID_sha256;
         return 1;
 
index 62fd9e0..0687c1e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -174,6 +174,8 @@ static const ERR_STRING_DATA RSA_str_reasons[] = {
     {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_LAST_OCTET_INVALID), "last octet invalid"},
     {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MGF1_DIGEST_NOT_ALLOWED),
     "mgf1 digest not allowed"},
+    {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MISSING_PRIVATE_KEY),
+    "missing private key"},
     {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MODULUS_TOO_LARGE), "modulus too large"},
     {ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R),
     "mp coefficient not inverse of r"},
index 4997a63..2b81808 100644 (file)
@@ -250,7 +250,7 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
              *
              * This strategy has the following goals:
              *
-             * 1. 1024-bit factors are effcient when using 3072 and 4096-bit key
+             * 1. 1024-bit factors are efficient when using 3072 and 4096-bit key
              * 2. stay the same logic with normal 2-prime key
              */
             bitse -= bitsr[i];
index 49c34b7..e737a28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -198,6 +198,7 @@ int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
     if (d != NULL) {
         BN_clear_free(r->d);
         r->d = d;
+        BN_set_flags(r->d, BN_FLG_CONSTTIME);
     }
 
     return 1;
@@ -215,10 +216,12 @@ int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
     if (p != NULL) {
         BN_clear_free(r->p);
         r->p = p;
+        BN_set_flags(r->p, BN_FLG_CONSTTIME);
     }
     if (q != NULL) {
         BN_clear_free(r->q);
         r->q = q;
+        BN_set_flags(r->q, BN_FLG_CONSTTIME);
     }
 
     return 1;
@@ -237,14 +240,17 @@ int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
     if (dmp1 != NULL) {
         BN_clear_free(r->dmp1);
         r->dmp1 = dmp1;
+        BN_set_flags(r->dmp1, BN_FLG_CONSTTIME);
     }
     if (dmq1 != NULL) {
         BN_clear_free(r->dmq1);
         r->dmq1 = dmq1;
+        BN_set_flags(r->dmq1, BN_FLG_CONSTTIME);
     }
     if (iqmp != NULL) {
         BN_clear_free(r->iqmp);
         r->iqmp = iqmp;
+        BN_set_flags(r->iqmp, BN_FLG_CONSTTIME);
     }
 
     return 1;
@@ -276,12 +282,15 @@ int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[],
         if (pinfo == NULL)
             goto err;
         if (primes[i] != NULL && exps[i] != NULL && coeffs[i] != NULL) {
-            BN_free(pinfo->r);
-            BN_free(pinfo->d);
-            BN_free(pinfo->t);
+            BN_clear_free(pinfo->r);
+            BN_clear_free(pinfo->d);
+            BN_clear_free(pinfo->t);
             pinfo->r = primes[i];
             pinfo->d = exps[i];
             pinfo->t = coeffs[i];
+            BN_set_flags(pinfo->r, BN_FLG_CONSTTIME);
+            BN_set_flags(pinfo->d, BN_FLG_CONSTTIME);
+            BN_set_flags(pinfo->t, BN_FLG_CONSTTIME);
         } else {
             rsa_multip_info_free(pinfo);
             goto err;
index 33be9ea..c8c3b78 100644 (file)
@@ -321,6 +321,11 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from,
             RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
             goto err;
         }
+        if (rsa->d == NULL) {
+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_MISSING_PRIVATE_KEY);
+            BN_free(d);
+            goto err;
+        }
         BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
 
         if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx,
@@ -438,6 +443,11 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
             RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
             goto err;
         }
+        if (rsa->d == NULL) {
+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_MISSING_PRIVATE_KEY);
+            BN_free(d);
+            goto err;
+        }
         BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
 
         if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
index e7c7f0a..5d58b2d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2010-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -29,7 +29,7 @@ struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
 void OPENSSL_cpuid_setup(void)
 {
     sigset_t oset;
-    struct sigaction ill_act, oact;
+    struct sigaction ill_act, oact_ill, oact_fpe;
 
     if (OPENSSL_s390xcap_P.stfle[0])
         return;
@@ -44,8 +44,8 @@ void OPENSSL_cpuid_setup(void)
     sigdelset(&ill_act.sa_mask, SIGFPE);
     sigdelset(&ill_act.sa_mask, SIGTRAP);
     sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
-    sigaction(SIGILL, &ill_act, &oact);
-    sigaction(SIGFPE, &ill_act, &oact);
+    sigaction(SIGILL, &ill_act, &oact_ill);
+    sigaction(SIGFPE, &ill_act, &oact_fpe);
 
     /* protection against missing store-facility-list-extended */
     if (sigsetjmp(ill_jmp, 1) == 0)
@@ -61,7 +61,7 @@ void OPENSSL_cpuid_setup(void)
                                          | S390X_CAPBIT(S390X_VXE));
     }
 
-    sigaction(SIGFPE, &oact, NULL);
-    sigaction(SIGILL, &oact, NULL);
+    sigaction(SIGFPE, &oact_fpe, NULL);
+    sigaction(SIGILL, &oact_ill, NULL);
     sigprocmask(SIG_SETMASK, &oset, NULL);
 }
index 8bf665c..cb8ccc9 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env perl
-# Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -1104,9 +1104,9 @@ KeccakF1600_neon:
 .align 4
 .Loop_neon:
        @ Theta
-       vst1.64         {q4},  [r0:64]          @ offload A[0..1][4]
+       vst1.64         {q4},  [r0,:64]         @ offload A[0..1][4]
        veor            q13, q0,  q5            @ A[0..1][0]^A[2..3][0]
-       vst1.64         {d18}, [r1:64]          @ offload A[2][4]
+       vst1.64         {d18}, [r1,:64]         @ offload A[2][4]
        veor            q14, q1,  q6            @ A[0..1][1]^A[2..3][1]
        veor            q15, q2,  q7            @ A[0..1][2]^A[2..3][2]
        veor            d26, d26, d27           @ C[0]=A[0][0]^A[1][0]^A[2][0]^A[3][0]
@@ -1149,10 +1149,10 @@ KeccakF1600_neon:
        veor            d16, d16, d28           @ A[2][3] ^= C[2]
        veor            d17, d17, d28           @ A[3][3] ^= C[2]
        veor            d23, d23, d28           @ A[4][3] ^= C[2]
-       vld1.64         {q4},  [r0:64]          @ restore A[0..1][4]
+       vld1.64         {q4},  [r0,:64]         @ restore A[0..1][4]
        vmov            d28, d29
 
-       vld1.64         {d18}, [r1:64]          @ restore A[2][4]
+       vld1.64         {d18}, [r1,:64]         @ restore A[2][4]
        veor            q2,  q2,  q13           @ A[0..1][2] ^= D[2]
        veor            q7,  q7,  q13           @ A[2..3][2] ^= D[2]
        veor            d22, d22, d27           @ A[4][2]    ^= D[2]
@@ -1227,7 +1227,7 @@ KeccakF1600_neon:
        veor            q13, q13, q0            @ A[0..1][0] ^ (~A[0..1][1] & A[0..1][2])
        veor            q14, q14, q1            @ A[0..1][1] ^ (~A[0..1][2] & A[0..1][3])
        veor            q2,  q2,  q15           @ A[0..1][2] ^= (~A[0..1][3] & A[0..1][4])
-       vst1.64         {q13}, [r0:64]          @ offload A[0..1][0]
+       vst1.64         {q13}, [r0,:64]         @ offload A[0..1][0]
        vbic            q13, q0,  q4
        vbic            q15, q1,  q0
        vmov            q1,  q14                @ A[0..1][1]
@@ -1248,10 +1248,10 @@ KeccakF1600_neon:
        vmov            q14, q10                @ A[4][0..1]
        veor            q9,  q9,  q13           @ A[2..3][4] ^= (~A[2..3][0] & A[2..3][1])
 
-       vld1.64         d25, [r2:64]!           @ Iota[i++]
+       vld1.64         d25, [r2,:64]!          @ Iota[i++]
        vbic            d26, d22, d21
        vbic            d27, d23, d22
-       vld1.64         {q0}, [r0:64]           @ restore A[0..1][0]
+       vld1.64         {q0}, [r0,:64]          @ restore A[0..1][0]
        veor            d20, d20, d26           @ A[4][0] ^= (~A[4][1] & A[4][2])
        vbic            d26, d24, d23
        veor            d21, d21, d27           @ A[4][1] ^= (~A[4][2] & A[4][3])
@@ -1279,32 +1279,32 @@ SHA3_absorb_neon:
        mov     r5, r2                  @ len
        mov     r6, r3                  @ bsz
 
-       vld1.32 {d0}, [r0:64]!          @ A[0][0]
-       vld1.32 {d2}, [r0:64]!          @ A[0][1]
-       vld1.32 {d4}, [r0:64]!          @ A[0][2]
-       vld1.32 {d6}, [r0:64]!          @ A[0][3]
-       vld1.32 {d8}, [r0:64]!          @ A[0][4]
-
-       vld1.32 {d1}, [r0:64]!          @ A[1][0]
-       vld1.32 {d3}, [r0:64]!          @ A[1][1]
-       vld1.32 {d5}, [r0:64]!          @ A[1][2]
-       vld1.32 {d7}, [r0:64]!          @ A[1][3]
-       vld1.32 {d9}, [r0:64]!          @ A[1][4]
-
-       vld1.32 {d10}, [r0:64]!         @ A[2][0]
-       vld1.32 {d12}, [r0:64]!         @ A[2][1]
-       vld1.32 {d14}, [r0:64]!         @ A[2][2]
-       vld1.32 {d16}, [r0:64]!         @ A[2][3]
-       vld1.32 {d18}, [r0:64]!         @ A[2][4]
-
-       vld1.32 {d11}, [r0:64]!         @ A[3][0]
-       vld1.32 {d13}, [r0:64]!         @ A[3][1]
-       vld1.32 {d15}, [r0:64]!         @ A[3][2]
-       vld1.32 {d17}, [r0:64]!         @ A[3][3]
-       vld1.32 {d19}, [r0:64]!         @ A[3][4]
-
-       vld1.32 {d20-d23}, [r0:64]!     @ A[4][0..3]
-       vld1.32 {d24}, [r0:64]          @ A[4][4]
+       vld1.32 {d0}, [r0,:64]!         @ A[0][0]
+       vld1.32 {d2}, [r0,:64]!         @ A[0][1]
+       vld1.32 {d4}, [r0,:64]!         @ A[0][2]
+       vld1.32 {d6}, [r0,:64]!         @ A[0][3]
+       vld1.32 {d8}, [r0,:64]!         @ A[0][4]
+
+       vld1.32 {d1}, [r0,:64]!         @ A[1][0]
+       vld1.32 {d3}, [r0,:64]!         @ A[1][1]
+       vld1.32 {d5}, [r0,:64]!         @ A[1][2]
+       vld1.32 {d7}, [r0,:64]!         @ A[1][3]
+       vld1.32 {d9}, [r0,:64]!         @ A[1][4]
+
+       vld1.32 {d10}, [r0,:64]!                @ A[2][0]
+       vld1.32 {d12}, [r0,:64]!                @ A[2][1]
+       vld1.32 {d14}, [r0,:64]!                @ A[2][2]
+       vld1.32 {d16}, [r0,:64]!                @ A[2][3]
+       vld1.32 {d18}, [r0,:64]!                @ A[2][4]
+
+       vld1.32 {d11}, [r0,:64]!                @ A[3][0]
+       vld1.32 {d13}, [r0,:64]!                @ A[3][1]
+       vld1.32 {d15}, [r0,:64]!                @ A[3][2]
+       vld1.32 {d17}, [r0,:64]!                @ A[3][3]
+       vld1.32 {d19}, [r0,:64]!                @ A[3][4]
+
+       vld1.32 {d20-d23}, [r0,:64]!    @ A[4][0..3]
+       vld1.32 {d24}, [r0,:64]         @ A[4][4]
        sub     r0, r0, #24*8           @ rewind
        b       .Loop_absorb_neon
 
@@ -1411,32 +1411,32 @@ SHA3_absorb_neon:
 
 .align 4
 .Labsorbed_neon:
-       vst1.32 {d0}, [r0:64]!          @ A[0][0..4]
-       vst1.32 {d2}, [r0:64]!
-       vst1.32 {d4}, [r0:64]!
-       vst1.32 {d6}, [r0:64]!
-       vst1.32 {d8}, [r0:64]!
-
-       vst1.32 {d1}, [r0:64]!          @ A[1][0..4]
-       vst1.32 {d3}, [r0:64]!
-       vst1.32 {d5}, [r0:64]!
-       vst1.32 {d7}, [r0:64]!
-       vst1.32 {d9}, [r0:64]!
-
-       vst1.32 {d10}, [r0:64]!         @ A[2][0..4]
-       vst1.32 {d12}, [r0:64]!
-       vst1.32 {d14}, [r0:64]!
-       vst1.32 {d16}, [r0:64]!
-       vst1.32 {d18}, [r0:64]!
-
-       vst1.32 {d11}, [r0:64]!         @ A[3][0..4]
-       vst1.32 {d13}, [r0:64]!
-       vst1.32 {d15}, [r0:64]!
-       vst1.32 {d17}, [r0:64]!
-       vst1.32 {d19}, [r0:64]!
-
-       vst1.32 {d20-d23}, [r0:64]!     @ A[4][0..4]
-       vst1.32 {d24}, [r0:64]
+       vst1.32 {d0}, [r0,:64]!         @ A[0][0..4]
+       vst1.32 {d2}, [r0,:64]!
+       vst1.32 {d4}, [r0,:64]!
+       vst1.32 {d6}, [r0,:64]!
+       vst1.32 {d8}, [r0,:64]!
+
+       vst1.32 {d1}, [r0,:64]!         @ A[1][0..4]
+       vst1.32 {d3}, [r0,:64]!
+       vst1.32 {d5}, [r0,:64]!
+       vst1.32 {d7}, [r0,:64]!
+       vst1.32 {d9}, [r0,:64]!
+
+       vst1.32 {d10}, [r0,:64]!                @ A[2][0..4]
+       vst1.32 {d12}, [r0,:64]!
+       vst1.32 {d14}, [r0,:64]!
+       vst1.32 {d16}, [r0,:64]!
+       vst1.32 {d18}, [r0,:64]!
+
+       vst1.32 {d11}, [r0,:64]!                @ A[3][0..4]
+       vst1.32 {d13}, [r0,:64]!
+       vst1.32 {d15}, [r0,:64]!
+       vst1.32 {d17}, [r0,:64]!
+       vst1.32 {d19}, [r0,:64]!
+
+       vst1.32 {d20-d23}, [r0,:64]!    @ A[4][0..4]
+       vst1.32 {d24}, [r0,:64]
 
        mov     r0, r5                  @ return value
        vldmia  sp!, {d8-d15}
@@ -1471,64 +1471,64 @@ SHA3_squeeze_neon:
 
        vstmdb  sp!,  {d8-d15}
 
-       vld1.32 {d0}, [r0:64]!          @ A[0][0..4]
-       vld1.32 {d2}, [r0:64]!
-       vld1.32 {d4}, [r0:64]!
-       vld1.32 {d6}, [r0:64]!
-       vld1.32 {d8}, [r0:64]!
-
-       vld1.32 {d1}, [r0:64]!          @ A[1][0..4]
-       vld1.32 {d3}, [r0:64]!
-       vld1.32 {d5}, [r0:64]!
-       vld1.32 {d7}, [r0:64]!
-       vld1.32 {d9}, [r0:64]!
-
-       vld1.32 {d10}, [r0:64]!         @ A[2][0..4]
-       vld1.32 {d12}, [r0:64]!
-       vld1.32 {d14}, [r0:64]!
-       vld1.32 {d16}, [r0:64]!
-       vld1.32 {d18}, [r0:64]!
-
-       vld1.32 {d11}, [r0:64]!         @ A[3][0..4]
-       vld1.32 {d13}, [r0:64]!
-       vld1.32 {d15}, [r0:64]!
-       vld1.32 {d17}, [r0:64]!
-       vld1.32 {d19}, [r0:64]!
-
-       vld1.32 {d20-d23}, [r0:64]!     @ A[4][0..4]
-       vld1.32 {d24}, [r0:64]
+       vld1.32 {d0}, [r0,:64]!         @ A[0][0..4]
+       vld1.32 {d2}, [r0,:64]!
+       vld1.32 {d4}, [r0,:64]!
+       vld1.32 {d6}, [r0,:64]!
+       vld1.32 {d8}, [r0,:64]!
+
+       vld1.32 {d1}, [r0,:64]!         @ A[1][0..4]
+       vld1.32 {d3}, [r0,:64]!
+       vld1.32 {d5}, [r0,:64]!
+       vld1.32 {d7}, [r0,:64]!
+       vld1.32 {d9}, [r0,:64]!
+
+       vld1.32 {d10}, [r0,:64]!                @ A[2][0..4]
+       vld1.32 {d12}, [r0,:64]!
+       vld1.32 {d14}, [r0,:64]!
+       vld1.32 {d16}, [r0,:64]!
+       vld1.32 {d18}, [r0,:64]!
+
+       vld1.32 {d11}, [r0,:64]!                @ A[3][0..4]
+       vld1.32 {d13}, [r0,:64]!
+       vld1.32 {d15}, [r0,:64]!
+       vld1.32 {d17}, [r0,:64]!
+       vld1.32 {d19}, [r0,:64]!
+
+       vld1.32 {d20-d23}, [r0,:64]!    @ A[4][0..4]
+       vld1.32 {d24}, [r0,:64]
        sub     r0, r0, #24*8           @ rewind
 
        bl      KeccakF1600_neon
 
        mov     r12, r0                 @ A_flat
-       vst1.32 {d0}, [r0:64]!          @ A[0][0..4]
-       vst1.32 {d2}, [r0:64]!
-       vst1.32 {d4}, [r0:64]!
-       vst1.32 {d6}, [r0:64]!
-       vst1.32 {d8}, [r0:64]!
-
-       vst1.32 {d1}, [r0:64]!          @ A[1][0..4]
-       vst1.32 {d3}, [r0:64]!
-       vst1.32 {d5}, [r0:64]!
-       vst1.32 {d7}, [r0:64]!
-       vst1.32 {d9}, [r0:64]!
-
-       vst1.32 {d10}, [r0:64]!         @ A[2][0..4]
-       vst1.32 {d12}, [r0:64]!
-       vst1.32 {d14}, [r0:64]!
-       vst1.32 {d16}, [r0:64]!
-       vst1.32 {d18}, [r0:64]!
-
-       vst1.32 {d11}, [r0:64]!         @ A[3][0..4]
-       vst1.32 {d13}, [r0:64]!
-       vst1.32 {d15}, [r0:64]!
-       vst1.32 {d17}, [r0:64]!
-       vst1.32 {d19}, [r0:64]!
-
-       vst1.32 {d20-d23}, [r0:64]!     @ A[4][0..4]
+       vst1.32 {d0}, [r0,:64]!         @ A[0][0..4]
+       vst1.32 {d2}, [r0,:64]!
+       vst1.32 {d4}, [r0,:64]!
+       vst1.32 {d6}, [r0,:64]!
+       vst1.32 {d8}, [r0,:64]!
+
+       vst1.32 {d1}, [r0,:64]!         @ A[1][0..4]
+       vst1.32 {d3}, [r0,:64]!
+       vst1.32 {d5}, [r0,:64]!
+       vst1.32 {d7}, [r0,:64]!
+       vst1.32 {d9}, [r0,:64]!
+
+       vst1.32 {d10}, [r0,:64]!                @ A[2][0..4]
+       vst1.32 {d12}, [r0,:64]!
+       vst1.32 {d14}, [r0,:64]!
+       vst1.32 {d16}, [r0,:64]!
+       vst1.32 {d18}, [r0,:64]!
+
+       vst1.32 {d11}, [r0,:64]!                @ A[3][0..4]
+       vst1.32 {d13}, [r0,:64]!
+       vst1.32 {d15}, [r0,:64]!
+       vst1.32 {d17}, [r0,:64]!
+       vst1.32 {d19}, [r0,:64]!
+
+       vst1.32 {d20-d23}, [r0,:64]!    @ A[4][0..4]
        mov     r14, r6                 @ bsz
-       vst1.32 {d24}, [r0:64]
+       vst1.32 {d24}, [r0,:64]
        mov     r0,  r12                @ rewind
 
        vldmia  sp!, {d8-d15}
index a3117bd..3173c77 100755 (executable)
@@ -738,7 +738,7 @@ $code.=<<___;
        blo     .Lprocess_block_ce
        ldr     d31,[$inp],#8           // *inp++
 #ifdef __AARCH64EB__
-       rev     v31.16b,v31.16b
+       rev64   v31.16b,v31.16b
 #endif
        eor     $A[$j/5][$j%5],$A[$j/5][$j%5],v31.16b
        beq     .Lprocess_block_ce
@@ -747,7 +747,7 @@ ___
 $code.=<<___;
        ldr     d31,[$inp],#8           // *inp++
 #ifdef __AARCH64EB__
-       rev     v31.16b,v31.16b
+       rev64   v31.16b,v31.16b
 #endif
        eor     $A[4][4],$A[4][4],v31.16b
 
index 4432bda..c215909 100644 (file)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -27,7 +27,7 @@
 # over 2x than 32-bit code. X[16] resides on stack, but access to it
 # is scheduled for L2 latency and staged through 32 least significant
 # bits of %l0-%l7. The latter is done to achieve 32-/64-bit ABI
-# duality. Nevetheless it's ~40% faster than SHA256, which is pretty
+# duality. Nevertheless it's ~40% faster than SHA256, which is pretty
 # good [optimal coefficient is 50%].
 #
 # SHA512 on UltraSPARC T1.
index 0f9c14c..50ecb4d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright 2017 Ribose Inc. All Rights Reserved.
  * Ported from Ribose contributions from Botan.
  *
@@ -313,12 +313,12 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig,
 
     /*
      * B1: verify whether r' in [1,n-1], verification failed if not
-     * B2: vefify whether s' in [1,n-1], verification failed if not
+     * B2: verify whether s' in [1,n-1], verification failed if not
      * B3: set M'~=ZA || M'
      * B4: calculate e'=Hv(M'~)
      * B5: calculate t = (r' + s') modn, verification failed if t=0
      * B6: calculate the point (x1', y1')=[s']G + [t]PA
-     * B7: calculate R=(e'+x1') modn, verfication pass if yes, otherwise failed
+     * B7: calculate R=(e'+x1') modn, verification pass if yes, otherwise failed
      */
 
     ECDSA_SIG_get0(sig, &r, &s);
index 632e451..6f569ee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -172,7 +172,7 @@ typedef OSSL_STORE_INFO *(*file_try_decode_fn)(const char *pem_name,
 typedef int (*file_eof_fn)(void *handler_ctx);
 /*
  * The destroy_ctx function is used to destroy the handler_ctx that was
- * intiated by a repeatable try_decode fuction.  This is only used when
+ * initiated by a repeatable try_decode function.  This is only used when
  * the handler is marked repeatable.
  */
 typedef void (*file_destroy_ctx_fn)(void **handler_ctx);
@@ -470,7 +470,7 @@ static FILE_HANDLER PrivateKey_handler = {
 };
 
 /*
- * Public key decoder.  Only supports SubjectPublicKeyInfo formated keys.
+ * Public key decoder.  Only supports SubjectPublicKeyInfo formatted keys.
  */
 static OSSL_STORE_INFO *try_decode_PUBKEY(const char *pem_name,
                                           const char *pem_header,
@@ -860,10 +860,10 @@ static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader,
         if (ctx->_.dir.last_entry == NULL) {
             if (ctx->_.dir.last_errno != 0) {
                 char errbuf[256];
-                errno = ctx->_.dir.last_errno;
-                openssl_strerror_r(errno, errbuf, sizeof(errbuf));
                 OSSL_STOREerr(OSSL_STORE_F_FILE_OPEN, ERR_R_SYS_LIB);
-                ERR_add_error_data(1, errbuf);
+                errno = ctx->_.dir.last_errno;
+                if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
+                    ERR_add_error_data(1, errbuf);
                 goto err;
             }
             ctx->_.dir.end_reached = 1;
@@ -1260,11 +1260,11 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
                 if (!ctx->_.dir.end_reached) {
                     char errbuf[256];
                     assert(ctx->_.dir.last_errno != 0);
+                    OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD, ERR_R_SYS_LIB);
                     errno = ctx->_.dir.last_errno;
                     ctx->errcnt++;
-                    openssl_strerror_r(errno, errbuf, sizeof(errbuf));
-                    OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD, ERR_R_SYS_LIB);
-                    ERR_add_error_data(1, errbuf);
+                    if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
+                        ERR_add_error_data(1, errbuf);
                 }
                 return NULL;
             }
index 1c43547..7de2e31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -228,7 +228,7 @@ int OSSL_STORE_close(OSSL_STORE_CTX *ctx)
  * Functions to generate OSSL_STORE_INFOs, one function for each type we
  * support having in them as well as a generic constructor.
  *
- * In all cases, ownership of the object is transfered to the OSSL_STORE_INFO
+ * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO
  * and will therefore be freed when the OSSL_STORE_INFO is freed.
  */
 static OSSL_STORE_INFO *store_info_new(int type, void *data)
index 4b1940a..aabf0e0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 
 #if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
 
+# if defined(OPENSSL_SYS_UNIX)
+#  include <sys/types.h>
+#  include <unistd.h>
+# endif
+
 CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
 {
     CRYPTO_RWLOCK *lock;
@@ -133,4 +138,12 @@ int openssl_init_fork_handlers(void)
     return 0;
 }
 
+int openssl_get_fork_id(void)
+{
+# if defined(OPENSSL_SYS_UNIX)
+    return getpid();
+# else
+    return return 0;
+# endif
+}
 #endif
index 5a59779..1774a2b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 
 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS)
 
+# if defined(OPENSSL_SYS_UNIX)
+#  include <sys/types.h>
+#  include <unistd.h>
+#endif
+
 # ifdef PTHREAD_RWLOCK_INITIALIZER
 #  define USE_RWLOCK
 # endif
@@ -193,4 +198,9 @@ int openssl_init_fork_handlers(void)
 # endif
     return 0;
 }
+
+int openssl_get_fork_id(void)
+{
+    return getpid();
+}
 #endif
index b0b16fd..44a360f 100644 (file)
@@ -164,4 +164,8 @@ int openssl_init_fork_handlers(void)
     return 0;
 }
 
+int openssl_get_fork_id(void)
+{
+    return 0;
+}
 #endif
index 139485d..f550972 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -500,6 +500,7 @@ int UI_process(UI *ui)
     if (ui->meth->ui_flush != NULL)
         switch (ui->meth->ui_flush(ui)) {
         case -1:               /* Interrupt/Cancel/something... */
+            ui->flags &= ~UI_FLAG_REDOABLE;
             ok = -2;
             goto err;
         case 0:                /* Errors */
@@ -517,6 +518,7 @@ int UI_process(UI *ui)
                                              sk_UI_STRING_value(ui->strings,
                                                                 i))) {
             case -1:           /* Interrupt/Cancel/something... */
+                ui->flags &= ~UI_FLAG_REDOABLE;
                 ok = -2;
                 goto err;
             case 0:            /* Errors */
index 5ca418d..0ec9f0d 100644 (file)
@@ -79,7 +79,7 @@
  * systems that require something different.
  *
  * Note: we do not use SGTTY unless it's defined by the configuration.  We
- * may eventually opt to remove it's use entirely.
+ * may eventually opt to remove its use entirely.
  */
 
 # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
index b2b0964..65b1171 100644 (file)
 #include <openssl/crypto.h>
 #include <openssl/opensslconf.h>
 
-#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2) || defined(__DragonFly__)
-
-# include OPENSSL_UNISTD
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)
 
 int OPENSSL_issetugid(void)
 {
-    return issetugid();
+    return 0;
 }
 
-#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)
+#elif defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2) || defined(__DragonFly__)
+
+# include OPENSSL_UNISTD
 
 int OPENSSL_issetugid(void)
 {
-    return 0;
+    return issetugid();
 }
 
 #else
index 0cc92a3..2ae5c38 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -87,6 +87,7 @@ typedef unsigned long long u64;
 #ifndef PEDANTIC
 # if defined(_MSC_VER)
 #  if defined(_WIN64)            /* applies to both IA-64 and AMD64 */
+#   include <stdlib.h>
 #   pragma intrinsic(_rotl64)
 #   define ROTATE(a,n) _rotl64((a),n)
 #  endif
index b3760db..b691a83 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -327,10 +327,10 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
         /*
          * we have added it to the cache so now pull it out again
          */
-        CRYPTO_THREAD_write_lock(ctx->lock);
+        X509_STORE_lock(xl->store_ctx);
         j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp);
         tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
-        CRYPTO_THREAD_unlock(ctx->lock);
+        X509_STORE_unlock(xl->store_ctx);
 
         /* If a CRL, update the last file suffix added for this */
 
index 2d4c591..dc3b4f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -127,6 +127,10 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
                 if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) {
                     ii = 0;
                     count = X509_ATTRIBUTE_count(a);
+                    if (count == 0) {
+                      X509err(X509_F_X509_REQ_PRINT_EX, X509_R_INVALID_ATTRIBUTES);
+                      return 0;
+                    }
  get_next:
                     at = X509_ATTRIBUTE_get0_type(a, ii);
                     type = at->type;
index 63895ef..3c4566d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -314,7 +314,9 @@ void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
     ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
     if (!ttmp)
         return NULL;
-    if (atrtype != ASN1_TYPE_get(ttmp)) {
+    if (atrtype == V_ASN1_BOOLEAN
+            || atrtype == V_ASN1_NULL
+            || atrtype != ASN1_TYPE_get(ttmp)) {
         X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE);
         return NULL;
     }
index 02fad0c..833bfce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -450,9 +450,17 @@ STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
     STACK_OF(X509) *ret;
     int i;
     ret = sk_X509_dup(chain);
+    if (ret == NULL)
+        return NULL;
     for (i = 0; i < sk_X509_num(ret); i++) {
         X509 *x = sk_X509_value(ret, i);
-        X509_up_ref(x);
+        if (!X509_up_ref(x))
+            goto err;
     }
     return ret;
+ err:
+    while (i-- > 0)
+        X509_free (sk_X509_value(ret, i));
+    sk_X509_free(ret);
+    return NULL;
 }
index 739708e..c110d90 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -123,6 +123,8 @@ static const ERR_STRING_DATA X509_str_reasons[] = {
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE),
     "crl verify failure"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_IDP_MISMATCH), "idp mismatch"},
+    {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_ATTRIBUTES),
+    "invalid attributes"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DIRECTORY), "invalid directory"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_FIELD_NAME),
     "invalid field name"},
index 8ddd7ec..b7d2e66 100644 (file)
@@ -289,24 +289,25 @@ X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs,
 int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
                                   X509_NAME *name, X509_OBJECT *ret)
 {
-    X509_STORE *ctx = vs->ctx;
+    X509_STORE *store = vs->ctx;
     X509_LOOKUP *lu;
     X509_OBJECT stmp, *tmp;
     int i, j;
 
-    if (ctx == NULL)
+    if (store == NULL)
         return 0;
 
     stmp.type = X509_LU_NONE;
     stmp.data.ptr = NULL;
 
-    CRYPTO_THREAD_write_lock(ctx->lock);
-    tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
-    CRYPTO_THREAD_unlock(ctx->lock);
+
+    X509_STORE_lock(store);
+    tmp = X509_OBJECT_retrieve_by_subject(store->objs, type, name);
+    X509_STORE_unlock(store);
 
     if (tmp == NULL || type == X509_LU_CRL) {
-        for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
-            lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
+        for (i = 0; i < sk_X509_LOOKUP_num(store->get_cert_methods); i++) {
+            lu = sk_X509_LOOKUP_value(store->get_cert_methods, i);
             j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
             if (j) {
                 tmp = &stmp;
@@ -317,15 +318,16 @@ int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
             return 0;
     }
 
+    if (!X509_OBJECT_up_ref_count(tmp))
+        return 0;
+
     ret->type = tmp->type;
     ret->data.ptr = tmp->data.ptr;
 
-    X509_OBJECT_up_ref_count(ret);
-
     return 1;
 }
 
-static int x509_store_add(X509_STORE *ctx, void *x, int crl) {
+static int x509_store_add(X509_STORE *store, void *x, int crl) {
     X509_OBJECT *obj;
     int ret = 0, added = 0;
 
@@ -342,18 +344,20 @@ static int x509_store_add(X509_STORE *ctx, void *x, int crl) {
         obj->type = X509_LU_X509;
         obj->data.x509 = (X509 *)x;
     }
-    X509_OBJECT_up_ref_count(obj);
-
-    CRYPTO_THREAD_write_lock(ctx->lock);
+    if (!X509_OBJECT_up_ref_count(obj)) {
+        obj->type = X509_LU_NONE;
+        X509_OBJECT_free(obj);
+        return 0;
+    }
 
-    if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
+    X509_STORE_lock(store);
+    if (X509_OBJECT_retrieve_match(store->objs, obj)) {
         ret = 1;
     } else {
-        added = sk_X509_OBJECT_push(ctx->objs, obj);
+        added = sk_X509_OBJECT_push(store->objs, obj);
         ret = added != 0;
     }
-
-    CRYPTO_THREAD_unlock(ctx->lock);
+    X509_STORE_unlock(store);
 
     if (added == 0)             /* obj not pushed */
         X509_OBJECT_free(obj);
@@ -534,12 +538,13 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
     STACK_OF(X509) *sk = NULL;
     X509 *x;
     X509_OBJECT *obj;
+    X509_STORE *store = ctx->ctx;
 
-    if (ctx->ctx == NULL)
+    if (store == NULL)
         return NULL;
 
-    CRYPTO_THREAD_write_lock(ctx->ctx->lock);
-    idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+    X509_STORE_lock(store);
+    idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt);
     if (idx < 0) {
         /*
          * Nothing found in cache: do lookup to possibly add new objects to
@@ -547,7 +552,8 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
          */
         X509_OBJECT *xobj = X509_OBJECT_new();
 
-        CRYPTO_THREAD_unlock(ctx->ctx->lock);
+        X509_STORE_unlock(store);
+
         if (xobj == NULL)
             return NULL;
         if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) {
@@ -555,27 +561,31 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
             return NULL;
         }
         X509_OBJECT_free(xobj);
-        CRYPTO_THREAD_write_lock(ctx->ctx->lock);
-        idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+        X509_STORE_lock(store);
+        idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt);
         if (idx < 0) {
-            CRYPTO_THREAD_unlock(ctx->ctx->lock);
+            X509_STORE_unlock(store);
             return NULL;
         }
     }
 
     sk = sk_X509_new_null();
     for (i = 0; i < cnt; i++, idx++) {
-        obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+        obj = sk_X509_OBJECT_value(store->objs, idx);
         x = obj->data.x509;
-        X509_up_ref(x);
+        if (!X509_up_ref(x)) {
+            X509_STORE_unlock(store);
+            sk_X509_pop_free(sk, X509_free);
+            return NULL;
+        }
         if (!sk_X509_push(sk, x)) {
-            CRYPTO_THREAD_unlock(ctx->ctx->lock);
+            X509_STORE_unlock(store);
             X509_free(x);
             sk_X509_pop_free(sk, X509_free);
             return NULL;
         }
     }
-    CRYPTO_THREAD_unlock(ctx->ctx->lock);
+    X509_STORE_unlock(store);
     return sk;
 }
 
@@ -585,37 +595,42 @@ STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
     STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
     X509_CRL *x;
     X509_OBJECT *obj, *xobj = X509_OBJECT_new();
+    X509_STORE *store = ctx->ctx;
 
     /* Always do lookup to possibly add new CRLs to cache */
     if (sk == NULL
             || xobj == NULL
-            || ctx->ctx == NULL
+            || store == NULL
             || !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) {
         X509_OBJECT_free(xobj);
         sk_X509_CRL_free(sk);
         return NULL;
     }
     X509_OBJECT_free(xobj);
-    CRYPTO_THREAD_write_lock(ctx->ctx->lock);
-    idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
+    X509_STORE_lock(store);
+    idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, nm, &cnt);
     if (idx < 0) {
-        CRYPTO_THREAD_unlock(ctx->ctx->lock);
+        X509_STORE_unlock(store);
         sk_X509_CRL_free(sk);
         return NULL;
     }
 
     for (i = 0; i < cnt; i++, idx++) {
-        obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+        obj = sk_X509_OBJECT_value(store->objs, idx);
         x = obj->data.crl;
-        X509_CRL_up_ref(x);
+        if (!X509_CRL_up_ref(x)) {
+            X509_STORE_unlock(store);
+            sk_X509_CRL_pop_free(sk, X509_CRL_free);
+            return NULL;
+        }
         if (!sk_X509_CRL_push(sk, x)) {
-            CRYPTO_THREAD_unlock(ctx->ctx->lock);
+            X509_STORE_unlock(store);
             X509_CRL_free(x);
             sk_X509_CRL_pop_free(sk, X509_CRL_free);
             return NULL;
         }
     }
-    CRYPTO_THREAD_unlock(ctx->ctx->lock);
+    X509_STORE_unlock(store);
     return sk;
 }
 
@@ -663,6 +678,7 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
 {
     X509_NAME *xn;
     X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL;
+    X509_STORE *store = ctx->ctx;
     int i, ok, idx, ret;
 
     if (obj == NULL)
@@ -678,25 +694,28 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
     if (ctx->check_issued(ctx, x, obj->data.x509)) {
         if (x509_check_cert_time(ctx, obj->data.x509, -1)) {
             *issuer = obj->data.x509;
-            X509_up_ref(*issuer);
+            if (!X509_up_ref(*issuer)) {
+                *issuer = NULL;
+                ok = -1;
+            }
             X509_OBJECT_free(obj);
-            return 1;
+            return ok;
         }
     }
     X509_OBJECT_free(obj);
 
-    if (ctx->ctx == NULL)
+    if (store == NULL)
         return 0;
 
     /* Else find index of first cert accepted by 'check_issued' */
     ret = 0;
-    CRYPTO_THREAD_write_lock(ctx->ctx->lock);
-    idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
+    X509_STORE_lock(store);
+    idx = X509_OBJECT_idx_by_subject(store->objs, X509_LU_X509, xn);
     if (idx != -1) {            /* should be true as we've had at least one
                                  * match */
         /* Look through all matching certs for suitable issuer */
-        for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
-            pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
+        for (i = idx; i < sk_X509_OBJECT_num(store->objs); i++) {
+            pobj = sk_X509_OBJECT_value(store->objs, i);
             /* See if we've run past the matches */
             if (pobj->type != X509_LU_X509)
                 break;
@@ -717,9 +736,11 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
             }
         }
     }
-    CRYPTO_THREAD_unlock(ctx->ctx->lock);
-    if (*issuer)
-        X509_up_ref(*issuer);
+    if (*issuer && !X509_up_ref(*issuer)) {
+        *issuer = NULL;
+        ret = -1;
+    }
+    X509_STORE_unlock(store);
     return ret;
 }
 
index 4ced716..6be2c71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -1788,7 +1788,11 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
     static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1;
     ASN1_TIME *asn1_cmp_time = NULL;
     int i, day, sec, ret = 0;
-
+#ifdef CHARSET_EBCDIC
+    const char upper_z = 0x5A;
+#else
+    const char upper_z = 'Z';
+#endif
     /*
      * Note that ASN.1 allows much more slack in the time format than RFC5280.
      * In RFC5280, the representation is fixed:
@@ -1819,10 +1823,10 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
      * Digit and date ranges will be verified in the conversion methods.
      */
     for (i = 0; i < ctm->length - 1; i++) {
-        if (!ossl_isdigit(ctm->data[i]))
+        if (!ascii_isdigit(ctm->data[i]))
             return 0;
     }
-    if (ctm->data[ctm->length - 1] != 'Z')
+    if (ctm->data[ctm->length - 1] != upper_z)
         return 0;
 
     /*
index 832e6d1..dfcb909 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -157,15 +157,18 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
         break;
 
     case GEN_EMAIL:
-        BIO_printf(out, "email:%s", gen->d.ia5->data);
+        BIO_printf(out, "email:");
+        ASN1_STRING_print(out, gen->d.ia5);
         break;
 
     case GEN_DNS:
-        BIO_printf(out, "DNS:%s", gen->d.ia5->data);
+        BIO_printf(out, "DNS:");
+        ASN1_STRING_print(out, gen->d.ia5);
         break;
 
     case GEN_URI:
-        BIO_printf(out, "URI:%s", gen->d.ia5->data);
+        BIO_printf(out, "URI:");
+        ASN1_STRING_print(out, gen->d.ia5);
         break;
 
     case GEN_DIRNAME:
index 70b0397..2f06289 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -871,6 +871,20 @@ const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x)
     return (x->akid != NULL ? x->akid->keyid : NULL);
 }
 
+const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    return (x->akid != NULL ? x->akid->issuer : NULL);
+}
+
+const ASN1_INTEGER *X509_get0_authority_serial(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    return (x->akid != NULL ? x->akid->serial : NULL);
+}
+
 long X509_get_pathlen(X509 *x)
 {
     /* Called for side effect of caching extensions */
index d49725f..44ca2fe 100644 (file)
@@ -37,7 +37,7 @@ server-arg.exe : server-arg.obj
 server-cmod.exe : server-cmod.obj
 server-conf.exe : server-conf.obj
 
-# Stoopid MMS doesn't infer this automatically...
+# MMS doesn't infer this automatically...
 client-arg.obj : client-arg.c
 client-conf.obj : client-conf.c
 saccept.obj : saccept.c
index 46d9a56..3cef27f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2012-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -84,7 +84,7 @@ void aes_gcm_decrypt(void)
     EVP_CIPHER_CTX *ctx;
     int outlen, tmplen, rv;
     unsigned char outbuf[1024];
-    printf("AES GCM Derypt:\n");
+    printf("AES GCM Decrypt:\n");
     printf("Ciphertext:\n");
     BIO_dump_fp(stdout, gcm_ct, sizeof(gcm_ct));
     ctx = EVP_CIPHER_CTX_new();
index 2936cd6..3c42349 100644 (file)
@@ -255,7 +255,7 @@ Here is some skeleton code you can fill in:
 
                       /*
                        * process_rights() is supposed to be a procedure
-                       * that takes a string and it's length, interprets
+                       * that takes a string and its length, interprets
                        * it and sets the bits in the YOUR_RIGHTS pointed
                        * at by the third argument.
                        */
index 24f1b32..d49f042 100644 (file)
@@ -64,7 +64,7 @@ See the example below.
 
 =back
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 To list all the commands available to a dynamic engine:
 
@@ -109,7 +109,7 @@ L<config(5)>
 
 =head1 COPYRIGHT
 
-Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 3c89b8f..94198c1 100644 (file)
@@ -20,7 +20,7 @@ second colon.
 
 None.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 The error code:
 
@@ -36,7 +36,7 @@ to produce the error message:
 
 =head1 COPYRIGHT
 
-Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2004-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 6f890c1..da887a4 100644 (file)
@@ -225,7 +225,8 @@ for this search. If the search fails it is considered a fatal error.
 
 Encrypt the certificate using triple DES, this may render the PKCS#12
 file unreadable by some "export grade" software. By default the private
-key is encrypted using triple DES and the certificate using 40 bit RC2.
+key is encrypted using triple DES and the certificate using 40 bit RC2
+unless RC2 is disabled in which case triple DES is used.
 
 =item B<-keypbe alg>, B<-certpbe alg>
 
index 5094965..bddabc2 100644 (file)
@@ -60,7 +60,7 @@ This option checks the correctness of parameters.
 
 =back
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Print out text version of parameters:
 
@@ -78,7 +78,7 @@ L<dsa(1)>, L<genrsa(1)>, L<gendsa(1)>
 
 =head1 COPYRIGHT
 
-Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 15752b5..e2475ea 100644 (file)
@@ -147,7 +147,7 @@ SSL servers.
 =head1 OPTIONS
 
 In addition to the options below the B<s_client> utility also supports the
-common and client only options documented in the
+common and client only options documented
 in the "Supported Command Line Commands" section of the L<SSL_CONF_cmd(3)>
 manual page.
 
index 7687896..7fa382a 100644 (file)
@@ -193,7 +193,7 @@ for connections on a given port using SSL/TLS.
 =head1 OPTIONS
 
 In addition to the options below the B<s_server> utility also supports the
-common and server only options documented in the
+common and server only options documented
 in the "Supported Command Line Commands" section of the L<SSL_CONF_cmd(3)>
 manual page.
 
index 5dcf72e..eaf63b2 100644 (file)
@@ -130,7 +130,7 @@ ADMISSION_SYNTAX_set0_contentsOfAdmissions()
 functions free any existing value and set the pointer to the specified value.
 
 The B<ADMISSION> type has an authority name, authority object, and a
-stack of B<PROFSSION_INFO> items.
+stack of B<PROFESSION_INFO> items.
 The ADMISSIONS_get0_admissionAuthority(), ADMISSIONS_get0_namingAuthority(),
 and ADMISSIONS_get0_professionInfos()
 functions return pointers to those values within the object.
@@ -169,7 +169,7 @@ L<d2i_X509(3)>,
 
 =head1 COPYRIGHT
 
-Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 9bd1044..b06db76 100644 (file)
@@ -170,7 +170,7 @@ is included, commonly as one of the first included headers. Therefore
 it is defined as an application developer's responsibility to include
 windows.h prior to async.h.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 The following example demonstrates how to use most of the core async APIs:
 
@@ -321,7 +321,7 @@ added in OpenSSL 1.1.0.
 
 =head1 COPYRIGHT
 
-Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 2766c3d..853315a 100644 (file)
@@ -24,7 +24,7 @@ but is present for future use.
 
 BIO_bind() binds the source address and service to a socket and
 may be useful before calling BIO_connect().  The options may include
-B<BIO_SOCK_REUSADDR>, which is described in L</FLAGS> below.
+B<BIO_SOCK_REUSEADDR>, which is described in L</FLAGS> below.
 
 BIO_connect() connects B<sock> to the address and service given by
 B<addr>.  Connection B<options> may be zero or any combination of
index e069594..59cccbd 100644 (file)
@@ -129,9 +129,25 @@ BIO_set_ssl(), BIO_get_ssl(), BIO_set_ssl_mode(),
 BIO_set_ssl_renegotiate_bytes(), BIO_set_ssl_renegotiate_timeout(),
 BIO_get_num_renegotiates(), and BIO_do_handshake() are implemented as macros.
 
-=head1 EXAMPLE
+=head1 RETURN VALUES
+
+BIO_f_ssl() returns the SSL B<BIO_METHOD> structure.
+
+BIO_set_ssl(), BIO_get_ssl(), BIO_set_ssl_mode(), BIO_set_ssl_renegotiate_bytes(),
+BIO_set_ssl_renegotiate_timeout() and BIO_get_num_renegotiates() return 1 on
+success or a value which is less than or equal to 0 if an error occurred.
+
+BIO_new_ssl(), BIO_new_ssl_connect() and BIO_new_buffer_ssl_connect() return
+a valid B<BIO> structure on success or B<NULL> if an error occurred.
+
+BIO_ssl_copy_session_id() returns 1 on success or 0 on error.
+
+BIO_do_handshake() returns 1 if the connection was established successfully.
+A zero or negative value is returned if the connection could not be established.
+
+=head1 EXAMPLES
 
-This SSL/TLS client example, attempts to retrieve a page from an
+This SSL/TLS client example attempts to retrieve a page from an
 SSL/TLS web server. The I/O routines are identical to those of the
 unencrypted example in L<BIO_s_connect(3)>.
 
@@ -271,22 +287,6 @@ a client and also echoes the request to standard output.
  BIO_flush(sbio);
  BIO_free_all(sbio);
 
-=head1 RETURN VALUES
-
-BIO_f_ssl() returns the SSL B<BIO_METHOD> structure.
-
-BIO_set_ssl(), BIO_get_ssl(), BIO_set_ssl_mode(), BIO_set_ssl_renegotiate_bytes(),
-BIO_set_ssl_renegotiate_timeout() and BIO_get_num_renegotiates() return 1 on
-success or a value which is less than or equal to 0 if an error occurred.
-
-BIO_new_ssl(), BIO_new_ssl_connect() and BIO_new_buffer_ssl_connect() return
-a valid B<BIO> structure on success or B<NULL> if an error occurred.
-
-BIO_ssl_copy_session_id() returns 1 on success or 0 on error.
-
-BIO_do_handshake() returns 1 if the connection was established successfully.
-A zero or negative value is returned if the connection could not be established.
-
 =head1 HISTORY
 
 In OpenSSL before 1.0.0 the BIO_pop() call was handled incorrectly,
@@ -298,7 +298,7 @@ be modified to handle this fix or they may free up an already freed BIO.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index b817194..b18b615 100644 (file)
@@ -40,7 +40,7 @@ BIO_next() returns the next BIO in a chain.
 
 BIO_method_type() returns the type of the BIO B<b>.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Traverse a chain looking for digest BIOs:
 
@@ -60,7 +60,7 @@ Traverse a chain looking for digest BIOs:
 
 =head1 COPYRIGHT
 
-Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 2712be0..c33eb9d 100644 (file)
@@ -53,7 +53,7 @@ on it other than the discarded return value.
 
 BIO_set() was removed in OpenSSL 1.1.0 as BIO type is now opaque.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Create a memory BIO:
 
@@ -61,7 +61,7 @@ Create a memory BIO:
 
 =head1 COPYRIGHT
 
-Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 45b864e..37b6f4d 100644 (file)
@@ -174,7 +174,7 @@ BIO_get_bind_mode() returns the set of B<BIO_BIND> flags, or -1 on failure.
 
 BIO_new_accept() returns a BIO or NULL on error.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example accepts two connections on port 4444, sends messages
 down each and finally closes both down.
@@ -224,7 +224,7 @@ down each and finally closes both down.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index dfafa35..f78fe13 100644 (file)
@@ -133,7 +133,7 @@ locations for B<bio1> and B<bio2>. Check the error stack for more information.
 
 [XXXXX: More return values need to be added here]
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 The BIO pair can be used to have full control over the network access of an
 application. The application can call select() on the socket as required
@@ -176,7 +176,7 @@ and must be transferred to the network. Use BIO_ctrl_get_read_request() to
 find out, how many bytes must be written into the buffer before the
 SSL_operation() can successfully be continued.
 
-=head1 WARNING
+=head1 WARNINGS
 
 As the data is buffered, SSL_operation() may return with an ERROR_SSL_WANT_READ
 condition, but there is still data in the write buffer. An application must
@@ -191,7 +191,7 @@ L<BIO_should_retry(3)>, L<BIO_read_ex(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index d5cc553..4f14529 100644 (file)
@@ -163,7 +163,7 @@ BIO_set_nbio() always returns 1.
 BIO_do_connect() returns 1 if the connection was successfully
 established and 0 or -1 if the connection failed.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This is example connects to a webserver on the local host and attempts
 to retrieve a page and copy the result to standard output.
@@ -203,7 +203,7 @@ Use BIO_set_conn_address() and BIO_get_conn_address() instead.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 8ebf563..6291373 100644 (file)
@@ -68,7 +68,7 @@ been initialized.
 BIO_new_fd() returns the newly allocated BIO or NULL is an error
 occurred.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This is a file descriptor BIO version of "Hello World":
 
@@ -88,7 +88,7 @@ L<BIO_set_close(3)>, L<BIO_get_close(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 2a5d423..9d3ae21 100644 (file)
@@ -41,9 +41,10 @@ If the BIO_CLOSE flag is set when a memory BIO is freed then the underlying
 BUF_MEM structure is also freed.
 
 Calling BIO_reset() on a read write memory BIO clears any data in it if the
-flag BIO_FLAGS_NONCLEAR_RST is not set. On a read only BIO or if the flag
-BIO_FLAGS_NONCLEAR_RST is set it restores the BIO to its original state and
-the data can be read again.
+flag BIO_FLAGS_NONCLEAR_RST is not set, otherwise it just restores the read
+pointer to the state it was just after the last write was performed and the
+data can be read again. On a read only BIO it similarly restores the BIO to
+its original state and the read only data can be read again.
 
 BIO_eof() is true if no data is in the BIO.
 
@@ -79,11 +80,11 @@ first, so the supplied area of memory must be unchanged until the BIO is freed.
 Writes to memory BIOs will always succeed if memory is available: that is
 their size can grow indefinitely.
 
-Every read from a read write memory BIO will remove the data just read with
-an internal copy operation, if a BIO contains a lot of data and it is
-read in small chunks the operation can be very slow. The use of a read only
-memory BIO avoids this problem. If the BIO must be read write then adding
-a buffering BIO to the chain will speed up the process.
+Every write after partial read (not all data in the memory buffer was read)
+to a read write memory BIO will have to move the unread data with an internal
+copy operation, if a BIO contains a lot of data and it is read in small
+chunks intertwined with writes the operation can be very slow. Adding
+a buffering BIO to the chain can speed up the process.
 
 Calling BIO_set_mem_buf() on a BIO created with BIO_new_secmem() will
 give undefined results, including perhaps a program crash.
@@ -104,11 +105,32 @@ BIO is set to BIO_NOCLOSE, before freeing the BUF_MEM the data pointer
 in it must be set to NULL as the data pointer does not point to an
 allocated memory.
 
+Calling BIO_reset() on a read write memory BIO with BIO_FLAGS_NONCLEAR_RST
+flag set can have unexpected outcome when the reads and writes to the
+BIO are intertwined. As documented above the BIO will be reset to the
+state after the last completed write operation. The effects of reads
+preceding that write operation cannot be undone.
+
+Calling BIO_get_mem_ptr() prior to a BIO_reset() call with
+BIO_FLAGS_NONCLEAR_RST set has the same effect as a write operation.
+
 =head1 BUGS
 
 There should be an option to set the maximum size of a memory BIO.
 
-=head1 EXAMPLE
+=head1 RETURN VALUES
+
+BIO_s_mem() and BIO_s_secmem() return a valid memory B<BIO_METHOD> structure.
+
+BIO_set_mem_eof_return(), BIO_set_mem_buf() and BIO_get_mem_ptr()
+return 1 on success or a value which is less than or equal to 0 if an error occurred.
+
+BIO_get_mem_data() returns the total number of bytes available on success,
+0 if b is NULL, or a negative value in case of other errors.
+
+BIO_new_mem_buf() returns a valid B<BIO> structure on success or NULL on error.
+
+=head1 EXAMPLES
 
 Create a memory BIO and write some data to it:
 
@@ -129,14 +151,6 @@ Extract the BUF_MEM structure from a memory BIO and then free up the BIO:
  BIO_set_close(mem, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */
  BIO_free(mem);
 
-=head1 RETURN VALUES
-
-BIO_s_mem() and BIO_s_secmem() return a valid memory B<BIO_METHOD> structure.
-
-BIO_set_mem_eof_return(), BIO_get_mem_data(), BIO_set_mem_buf() and BIO_get_mem_ptr()
-return 1 on success or a value which is less than or equal to 0 if an error occurred.
-
-BIO_new_mem_buf() returns a valid B<BIO> structure on success or NULL on error.
 
 =head1 COPYRIGHT
 
index 0a9b6ed..291456b 100644 (file)
@@ -211,11 +211,6 @@ the actual call parameter, see B<BIO_callback_ctrl>.
 
 =back
 
-=head1 EXAMPLE
-
-The BIO_debug_callback() function is a good example, its source is
-in crypto/bio/bio_cb.c
-
 =head1 RETURN VALUES
 
 BIO_get_callback_ex() and BIO_get_callback() return the callback function
@@ -228,9 +223,14 @@ via a call to BIO_set_callback_arg().
 BIO_debug_callback() returns 1 or B<ret> if it's called after specific BIO
 operations.
 
+=head1 EXAMPLES
+
+The BIO_debug_callback() function is a good example, its source is
+in crypto/bio/bio_cb.c
+
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index b6e9145..31fbc1f 100644 (file)
@@ -51,7 +51,9 @@ Deprecated:
 =head1 DESCRIPTION
 
 BN_generate_prime_ex() generates a pseudo-random prime number of
-at least bit length B<bits>.
+at least bit length B<bits>. The returned number is probably prime
+with a negligible error.
+
 If B<ret> is not B<NULL>, it will be used to store the number.
 
 If B<cb> is not B<NULL>, it is used as follows:
@@ -89,8 +91,9 @@ generator.
 If B<safe> is true, it will be a safe prime (i.e. a prime p so
 that (p-1)/2 is also prime).
 
-The PRNG must be seeded prior to calling BN_generate_prime_ex().
-The prime number generation has a negligible error probability.
+The random generator must be seeded prior to calling BN_generate_prime_ex().
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
 
 BN_is_prime_ex() and BN_is_prime_fasttest_ex() test if the number B<p> is
 prime.  The following tests are performed until one of them shows that
@@ -193,7 +196,8 @@ Instead applications should create a BN_GENCB structure using BN_GENCB_new:
 =head1 SEE ALSO
 
 L<DH_generate_parameters(3)>, L<DSA_generate_parameters(3)>,
-L<RSA_generate_key(3)>, L<ERR_get_error(3)>, L<RAND_bytes(3)>
+L<RSA_generate_key(3)>, L<ERR_get_error(3)>, L<RAND_bytes(3)>,
+L<RAND(7)>
 
 =head1 HISTORY
 
@@ -202,7 +206,7 @@ and BN_GENCB_get_arg() functions were added in OpenSSL 1.1.0.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 4dfcb21..7f47e94 100644 (file)
@@ -64,7 +64,7 @@ BN_MONT_CTX_free() has no return value.
 For the other functions, 1 is returned for success, 0 on error.
 The error codes can be obtained by L<ERR_get_error(3)>.
 
-=head1 WARNING
+=head1 WARNINGS
 
 The inputs must be reduced modulo B<m>, otherwise the result will be
 outside the expected range.
@@ -80,7 +80,7 @@ BN_MONT_CTX_init() was removed in OpenSSL 1.1.0
 
 =head1 COPYRIGHT
 
-Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 1fab6d2..7f0f651 100644 (file)
@@ -22,7 +22,7 @@ BN_new, BN_secure_new, BN_clear, BN_free, BN_clear_free - allocate and free BIGN
 
 BN_new() allocates and initializes a B<BIGNUM> structure.
 BN_secure_new() does the same except that the secure heap
-OPENSSL_secure_malloc(3) is used to store the value.
+L<OPENSSL_secure_malloc(3)> is used to store the value.
 
 BN_clear() is used to destroy sensitive data such as keys when they
 are no longer needed. It erases the memory used by B<a> and sets it
@@ -46,7 +46,7 @@ BN_clear(), BN_free() and BN_clear_free() have no return values.
 
 =head1 SEE ALSO
 
-L<ERR_get_error(3)>
+L<ERR_get_error(3)>, L<OPENSSL_secure_malloc(3)>
 
 =head1 HISTORY
 
index 264fe7b..15fd15a 100644 (file)
@@ -12,7 +12,7 @@ CMS_final - finalise a CMS_ContentInfo structure
 
 =head1 DESCRIPTION
 
-CMS_final() finalises the structure B<cms>. It's purpose is to perform any
+CMS_final() finalises the structure B<cms>. Its purpose is to perform any
 operations necessary on B<cms> (digest computation for example) and set the
 appropriate fields. The parameter B<data> contains the content to be
 processed. The B<dcont> parameter contains a BIO to write content to after
@@ -36,7 +36,7 @@ L<CMS_encrypt(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 3277613..b919e2e 100644 (file)
@@ -97,7 +97,7 @@ one of the first included headers. Therefore it is defined as an
 application developer's responsibility to include windows.h prior to
 crypto.h where use of CRYPTO_THREAD_* types and functions is required.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example safely initializes and uses a lock.
 
@@ -161,7 +161,7 @@ L<crypto(7)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/doc/man3/CRYPTO_memcmp.pod b/doc/man3/CRYPTO_memcmp.pod
new file mode 100644 (file)
index 0000000..9182d00
--- /dev/null
@@ -0,0 +1,39 @@
+=pod
+
+=head1 NAME
+
+CRYPTO_memcmp - Constant time memory comparison
+
+=head1 SYNOPSIS
+
+ #include <openssl/crypto.h>
+
+ int CRYPTO_memcmp(const void *a, const void *b, size_t len);
+
+=head1 DESCRIPTION
+
+The CRYPTO_memcmp function compares the B<len> bytes pointed to by B<a> and B<b>
+for equality.
+It takes an amount of time dependent on B<len>, but independent of the
+contents of the memory regions pointed to by B<a> and B<b>.
+
+=head1 RETURN VALUES
+
+CRYPTO_memcmp() returns 0 if the memory regions are equal and non-zero
+otherwise.
+
+=head1 NOTES
+
+Unlike memcmp(2), this function cannot be used to order the two memory regions
+as the return value when they differ is undefined, other than being non-zero.
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index bd4bd97..04df6ec 100644 (file)
@@ -104,9 +104,11 @@ consists of 8 bytes with odd parity.  The least significant bit in
 each byte is the parity bit.  The key schedule is an expanded form of
 the key; it is used to speed the encryption process.
 
-DES_random_key() generates a random key.  The PRNG must be seeded
-prior to using this function (see L<RAND_bytes(3)>).  If the PRNG
-could not generate a secure key, 0 is returned.
+DES_random_key() generates a random key.  The random generator must be
+seeded when calling this function.
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
+If the function fails, 0 is returned.
 
 Before a DES key can be used, it must be converted into the
 architecture dependent I<DES_key_schedule> via the
index 9ff7553..bb1bb36 100644 (file)
@@ -15,7 +15,9 @@ DSA_generate_key - generate DSA key pair
 DSA_generate_key() expects B<a> to contain DSA parameters. It generates
 a new key pair and stores it in B<a-E<gt>pub_key> and B<a-E<gt>priv_key>.
 
-The PRNG must be seeded prior to calling DSA_generate_key().
+The random generator must be seeded prior to calling DSA_generate_key().
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
 
 =head1 RETURN VALUES
 
@@ -29,7 +31,7 @@ L<DSA_generate_parameters_ex(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 889c7a1..0d76b8c 100644 (file)
@@ -36,8 +36,10 @@ B<dsa> is the signer's public key.
 
 The B<type> parameter is ignored.
 
-The PRNG must be seeded before DSA_sign() (or DSA_sign_setup())
+The random generator must be seeded when DSA_sign() (or DSA_sign_setup())
 is called.
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
 
 =head1 RETURN VALUES
 
@@ -54,11 +56,12 @@ Standard, DSS), ANSI X9.30
 =head1 SEE ALSO
 
 L<DSA_new(3)>, L<ERR_get_error(3)>, L<RAND_bytes(3)>,
-L<DSA_do_sign(3)>
+L<DSA_do_sign(3)>,
+L<RAND(7)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 8d6cda5..6a7d107 100644 (file)
@@ -3,10 +3,10 @@
 =head1 NAME
 
 ECDSA_SIG_get0, ECDSA_SIG_get0_r, ECDSA_SIG_get0_s, ECDSA_SIG_set0,
-ECDSA_SIG_new, ECDSA_SIG_free, i2d_ECDSA_SIG, d2i_ECDSA_SIG, ECDSA_size,
-ECDSA_sign, ECDSA_do_sign, ECDSA_verify, ECDSA_do_verify, ECDSA_sign_setup,
-ECDSA_sign_ex, ECDSA_do_sign_ex - low level elliptic curve digital signature
-algorithm (ECDSA) functions
+ECDSA_SIG_new, ECDSA_SIG_free, ECDSA_size, ECDSA_sign, ECDSA_do_sign,
+ECDSA_verify, ECDSA_do_verify, ECDSA_sign_setup, ECDSA_sign_ex,
+ECDSA_do_sign_ex - low level elliptic curve digital signature algorithm (ECDSA)
+functions
 
 =head1 SYNOPSIS
 
@@ -18,8 +18,6 @@ algorithm (ECDSA) functions
  const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig);
  const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig);
  int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
- int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
- ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
  int ECDSA_size(const EC_KEY *eckey);
 
  int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen,
@@ -68,15 +66,8 @@ function transfers the memory management of the values to the ECDSA_SIG object,
 and therefore the values that have been passed in should not be freed directly
 after this function has been called.
 
-i2d_ECDSA_SIG() creates the DER encoding of the ECDSA signature B<sig> and
-writes the encoded signature to B<*pp> (note: if B<pp> is NULL i2d_ECDSA_SIG()
-returns the expected length in bytes of the DER encoded signature).
-i2d_ECDSA_SIG() returns the length of the DER encoded signature (or 0 on
-error).
-
-d2i_ECDSA_SIG() decodes a DER encoded ECDSA signature and returns the decoded
-signature in a newly allocated B<ECDSA_SIG> structure. B<*sig> points to the
-buffer containing the DER encoded signature of size B<len>.
+See L<i2d_ECDSA_SIG(3)> and L<d2i_ECDSA_SIG(3)> for information about encoding
+and decoding ECDSA signatures to/from DER.
 
 ECDSA_size() returns the maximum length of a DER encoded ECDSA signature
 created with the private EC key B<eckey>.
@@ -202,7 +193,9 @@ ANSI X9.62, US Federal Information Processing Standard FIPS 186-2
 
 L<EC_KEY_new(3)>,
 L<EVP_DigestSignInit(3)>,
-L<EVP_DigestVerifyInit(3)>
+L<EVP_DigestVerifyInit(3)>,
+L<i2d_ECDSA_SIG(3)>,
+L<d2i_ECDSA_SIG(3)>
 
 =head1 COPYRIGHT
 
index 37bc10d..3e3e342 100644 (file)
@@ -304,7 +304,7 @@ macros.
 EVP_MD_CTX_ctrl() sends commands to message digests for additional configuration
 or control.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example digests the data "Test Message\n" and "Hello World\n", using the
 digest name passed on the command line.
@@ -381,7 +381,7 @@ The EVP_MD_CTX_set_pkey_ctx() function was added in 1.1.1.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 7b74a23..0bbc3d0 100644 (file)
@@ -35,7 +35,7 @@ EVP_MD_CTX is freed).
 
 The digest B<type> may be NULL if the signing algorithm supports it.
 
-No B<EVP_PKEY_CTX> will be created by EVP_DigsetSignInit() if the passed B<ctx>
+No B<EVP_PKEY_CTX> will be created by EVP_DigestSignInit() if the passed B<ctx>
 has already been assigned one via L<EVP_MD_CTX_set_ctx(3)>. See also L<SM2(7)>.
 
 Only EVP_PKEY types that support signing can be used with these functions. This
@@ -125,8 +125,9 @@ and public key algorithms. This meant that "clone" digests such as EVP_dss1()
 needed to be used to sign using SHA1 and DSA. This is no longer necessary and
 the use of clone digest is now discouraged.
 
-For some key types and parameters the random number generator must be seeded
-or the operation will fail.
+For some key types and parameters the random number generator must be seeded.
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
 
 The call to EVP_DigestSignFinal() internally finalizes a copy of the digest
 context. This means that calls to EVP_DigestSignUpdate() and
@@ -147,7 +148,8 @@ L<EVP_DigestVerifyInit(3)>,
 L<EVP_DigestInit(3)>,
 L<evp(7)>, L<HMAC(3)>, L<MD2(3)>,
 L<MD5(3)>, L<MDC2(3)>, L<RIPEMD160(3)>,
-L<SHA1(3)>, L<dgst(1)>
+L<SHA1(3)>, L<dgst(1)>,
+L<RAND(7)>
 
 =head1 HISTORY
 
@@ -156,7 +158,7 @@ were added in OpenSSL 1.0.0.
 
 =head1 COPYRIGHT
 
-Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 592a750..05b99bb 100644 (file)
@@ -32,7 +32,7 @@ being passed to EVP_DigestVerifyInit() (which means the EVP_PKEY_CTX is created
 inside EVP_DigestVerifyInit() and it will be freed automatically when the
 EVP_MD_CTX is freed).
 
-No B<EVP_PKEY_CTX> will be created by EVP_DigsetSignInit() if the passed B<ctx>
+No B<EVP_PKEY_CTX> will be created by EVP_DigestSignInit() if the passed B<ctx>
 has already been assigned one via L<EVP_MD_CTX_set_ctx(3)>. See also L<SM2(7)>.
 
 EVP_DigestVerifyUpdate() hashes B<cnt> bytes of data at B<d> into the
@@ -76,8 +76,9 @@ and public key algorithms. This meant that "clone" digests such as EVP_dss1()
 needed to be used to sign using SHA1 and DSA. This is no longer necessary and
 the use of clone digest is now discouraged.
 
-For some key types and parameters the random number generator must be seeded
-or the operation will fail.
+For some key types and parameters the random number generator must be seeded.
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
 
 The call to EVP_DigestVerifyFinal() internally finalizes a copy of the digest
 context. This means that EVP_VerifyUpdate() and EVP_VerifyFinal() can
@@ -93,7 +94,8 @@ L<EVP_DigestSignInit(3)>,
 L<EVP_DigestInit(3)>,
 L<evp(7)>, L<HMAC(3)>, L<MD2(3)>,
 L<MD5(3)>, L<MDC2(3)>, L<RIPEMD160(3)>,
-L<SHA1(3)>, L<dgst(1)>
+L<SHA1(3)>, L<dgst(1)>,
+L<RAND(7)>
 
 =head1 HISTORY
 
index e8f19cf..974bbed 100644 (file)
@@ -121,7 +121,7 @@ All these functions return 1 for success and 0 or a negative value for failure.
 In particular a return value of -2 indicates the operation is not supported by
 the public key algorithm.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example derives 10 bytes using SHA-256 with the secret key "secret",
 salt value "salt" and info value "label":
@@ -156,7 +156,7 @@ L<EVP_PKEY_derive(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 30e50bc..9a8d7a8 100644 (file)
@@ -70,7 +70,7 @@ All these functions return 1 for success and 0 or a negative value for failure.
 In particular a return value of -2 indicates the operation is not supported by
 the public key algorithm.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example derives 10 bytes using SHA-256 with the secret key "secret"
 and seed value "seed":
@@ -99,7 +99,7 @@ L<EVP_PKEY_derive(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 2e3d266..08d0ec3 100644 (file)
@@ -41,7 +41,7 @@ EVP_PKEY_decrypt_init() and EVP_PKEY_decrypt() return 1 for success and 0
 or a negative value for failure. In particular a return value of -2
 indicates the operation is not supported by the public key algorithm.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Decrypt data using OAEP (for RSA keys):
 
@@ -95,7 +95,7 @@ These functions were added in OpenSSL 1.0.0.
 
 =head1 COPYRIGHT
 
-Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index a74065e..76b3c39 100644 (file)
@@ -42,7 +42,7 @@ EVP_PKEY_derive_init() and EVP_PKEY_derive() return 1 for success and 0
 or a negative value for failure. In particular a return value of -2
 indicates the operation is not supported by the public key algorithm.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Derive shared secret (for example DH or EC keys):
 
@@ -93,7 +93,7 @@ These functions were added in OpenSSL 1.0.0.
 
 =head1 COPYRIGHT
 
-Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 3718910..2a3bf2a 100644 (file)
@@ -41,7 +41,7 @@ EVP_PKEY_encrypt_init() and EVP_PKEY_encrypt() return 1 for success and 0
 or a negative value for failure. In particular a return value of -2
 indicates the operation is not supported by the public key algorithm.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Encrypt data using OAEP (for RSA keys). See also L<PEM_read_PUBKEY(3)> or
 L<d2i_X509(3)> for means to load a public key. You may also simply
@@ -100,7 +100,7 @@ These functions were added in OpenSSL 1.0.0.
 
 =head1 COPYRIGHT
 
-Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 1672831..175aeed 100644 (file)
@@ -46,7 +46,7 @@ EVP_PKEY_sign_init() and EVP_PKEY_sign() return 1 for success and 0
 or a negative value for failure. In particular a return value of -2
 indicates the operation is not supported by the public key algorithm.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Sign data using RSA with PKCS#1 padding and SHA256 digest:
 
@@ -105,7 +105,7 @@ These functions were added in OpenSSL 1.0.0.
 
 =head1 COPYRIGHT
 
-Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index cdbb80b..616fd55 100644 (file)
@@ -44,7 +44,7 @@ A negative value indicates an error other that signature verification failure.
 In particular a return value of -2 indicates the operation is not supported by
 the public key algorithm.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Verify signature using PKCS#1 and SHA256 digest:
 
@@ -93,7 +93,7 @@ These functions were added in OpenSSL 1.0.0.
 
 =head1 COPYRIGHT
 
-Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 2513606..a3a7818 100644 (file)
@@ -49,7 +49,7 @@ EVP_PKEY_verify_recover_init() and EVP_PKEY_verify_recover() return 1 for succes
 and 0 or a negative value for failure. In particular a return value of -2
 indicates the operation is not supported by the public key algorithm.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Recover digest originally signed using PKCS#1 and SHA256 digest:
 
@@ -104,7 +104,7 @@ These functions were added in OpenSSL 1.0.0.
 
 =head1 COPYRIGHT
 
-Copyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2013-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 29d89c3..2c2c89a 100644 (file)
@@ -55,7 +55,9 @@ failure.
 =head1 NOTES
 
 Because a random secret key is generated the random number generator
-must be seeded before calling EVP_SealInit().
+must be seeded when EVP_SealInit() is called.
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
 
 The public key must be RSA because it is the only OpenSSL public key
 algorithm that supports key transport.
@@ -75,11 +77,12 @@ with B<type> set to NULL.
 
 L<evp(7)>, L<RAND_bytes(3)>,
 L<EVP_EncryptInit(3)>,
-L<EVP_OpenInit(3)>
+L<EVP_OpenInit(3)>,
+L<RAND(7)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 86fec82..c26b7f7 100644 (file)
@@ -66,9 +66,10 @@ The B<EVP> interface to digital signatures should almost always be used in
 preference to the low level interfaces. This is because the code then becomes
 transparent to the algorithm used and much more flexible.
 
-When signing with DSA private keys the random number generator must be seeded
-or the operation will fail. The random number generator does not need to be
-seeded for RSA signatures.
+When signing with DSA private keys the random number generator must be seeded.
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
+This requirement does not hold for RSA signatures.
 
 The call to EVP_SignFinal() internally finalizes a copy of the digest context.
 This means that calls to EVP_SignUpdate() and EVP_SignFinal() can be called
@@ -102,7 +103,7 @@ L<SHA1(3)>, L<dgst(1)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index f868258..647c99b 100644 (file)
@@ -72,7 +72,7 @@ data have been passed through EVP_SignUpdate().
 
 It is not possible to change the signing parameters using these function.
 
-The previous two bugs are fixed in the newer EVP_VerifyDigest*() function.
+The previous two bugs are fixed in the newer EVP_DigestVerify*() function.
 
 =head1 SEE ALSO
 
@@ -85,7 +85,7 @@ L<SHA1(3)>, L<dgst(1)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index fbb7918..c30ff99 100644 (file)
@@ -32,7 +32,7 @@ EVP_aria_256_ccm,
 EVP_aria_128_gcm,
 EVP_aria_192_gcm,
 EVP_aria_256_gcm,
-- EVP AES cipher
+- EVP ARIA cipher
 
 =head1 SYNOPSIS
 
@@ -106,7 +106,7 @@ L<EVP_CIPHER_meth_new(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 725fcbf..ed0f99c 100644 (file)
@@ -29,7 +29,7 @@ The MD5 algorithm which produces a 128-bit output from a given input.
 
 =item EVP_md5_sha1()
 
-A hash algorithm of SSL v3 that combines MD5 with SHA-1 as decirbed in RFC
+A hash algorithm of SSL v3 that combines MD5 with SHA-1 as described in RFC
 6101.
 
 WARNING: this algorithm is not intended for non-SSL usage.
@@ -54,7 +54,7 @@ L<EVP_DigestInit(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 442a114..9eb8bd9 100644 (file)
@@ -33,7 +33,26 @@ EVP_rc5_32_12_16_ofb()
 
 RC5 encryption algorithm in CBC, CFB, ECB and OFB modes respectively. This is a
 variable key length cipher with an additional "number of rounds" parameter. By
-default the key length is set to 128 bits and 12 rounds.
+default the key length is set to 128 bits and 12 rounds. Alternative key lengths
+can be set using L<EVP_CIPHER_CTX_set_key_length(3)>. The maximum key length is
+2040 bits.
+
+The following rc5 specific I<ctrl>s are supported (see
+L<EVP_CIPHER_CTX_ctrl(3)>).
+
+=over 4
+
+=item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC5_ROUNDS, rounds, NULL)
+
+Sets the number of rounds to B<rounds>. This must be one of RC5_8_ROUNDS,
+RC5_12_ROUNDS or RC5_16_ROUNDS.
+
+=item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC5_ROUNDS, 0, &rounds)
+
+Stores the number of rounds currently configured in B<*rounds> where B<*rounds>
+is an int.
+
+=back
 
 =back
 
@@ -43,10 +62,6 @@ These functions return an B<EVP_CIPHER> structure that contains the
 implementation of the symmetric cipher. See L<EVP_CIPHER_meth_new(3)> for
 details of the B<EVP_CIPHER> structure.
 
-=head1 BUGS
-
-Currently the number of rounds in RC5 can only be set to 8, 12 or 16.
-This is a limitation of the current RC5 code rather than the EVP interface.
 
 =head1 SEE ALSO
 
@@ -56,7 +71,7 @@ L<EVP_CIPHER_meth_new(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index a382b16..283c226 100644 (file)
@@ -75,7 +75,7 @@ corresponding to each certificate.
 OCSP_request_onereq_count() and OCSP_request_onereq_get0() are mainly used by
 OCSP responders.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Create an B<OCSP_REQUEST> structure for certificate B<cert> with issuer
 B<issuer>:
@@ -108,7 +108,7 @@ L<OCSP_sendreq_new(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 7c4eb1d..a47a07a 100644 (file)
@@ -24,7 +24,7 @@ The OPENSSL_fork_prepare(), OPENSSL_fork_parent(), and OPENSSL_fork_child()
 functions are used to reset this internal state.
 
 Platforms without fork(2) will probably not need to use these functions.
-Platforms with fork(2) but without pthreads_atfork(3) will probably need
+Platforms with fork(2) but without pthread_atfork(3) will probably need
 to call them manually, as described in the following paragraph.  Platforms
 such as Linux that have both functions will normally not need to call these
 functions as the OpenSSL library will do so automatically.
@@ -32,7 +32,7 @@ functions as the OpenSSL library will do so automatically.
 L<OPENSSL_init_crypto(3)> will register these functions with the appropriate
 handler, when the B<OPENSSL_INIT_ATFORK> flag is used. For other
 applications, these functions can be called directly. They should be used
-according to the calling sequence described by the pthreads_atfork(3)
+according to the calling sequence described by the pthread_atfork(3)
 documentation, which is summarized here.  OPENSSL_fork_prepare() should
 be called before a fork() is done.  After the fork() returns, the parent
 process should call OPENSSL_fork_parent() and the child process should
@@ -53,7 +53,7 @@ These functions were added in OpenSSL 1.1.1.
 
 =head1 COPYRIGHT
 
-Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 1503754..b0c15b0 100644 (file)
@@ -95,7 +95,7 @@ manner possible according to the scheme the loader implements, it also
 takes a B<UI_METHOD> and associated data, to be used any time
 something needs to be prompted for.
 Furthermore, this function is expected to initialize what needs to be
-initialized, to create a privata data store (B<OSSL_STORE_LOADER_CTX>, see
+initialized, to create a private data store (B<OSSL_STORE_LOADER_CTX>, see
 above), and to return it.
 If something goes wrong, this function is expected to return NULL.
 
@@ -254,7 +254,7 @@ were added in OpenSSL 1.1.1.
 
 =head1 COPYRIGHT
 
-Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 154472a..ff3fb2a 100644 (file)
@@ -32,7 +32,7 @@ grained search of objects.
 
 OSSL_STORE_supports_search() checks if the loader of the given OSSL_STORE
 context supports the given search type.
-See L<OSSL_STORE_SEARCH/SUPPORED CRITERION TYPES> for information on the
+See L<OSSL_STORE_SEARCH/SUPPORTED CRITERION TYPES> for information on the
 supported search criterion types.
 
 OSSL_STORE_expect() and OSSL_STORE_find I<must> be called before the first
@@ -69,7 +69,7 @@ were added in OpenSSL 1.1.1.
 
 =head1 COPYRIGHT
 
-Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 1c34ee5..5fc041b 100644 (file)
@@ -34,7 +34,7 @@ L<UI_OpenSSL(3)>, for example.
 PKCS12_newpass() returns 1 on success or 0 on failure. Applications can
 retrieve the most recent error from PKCS12_newpass() with ERR_get_error().
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example loads a PKCS#12 file, changes its password and writes out
 the result to a new file.
@@ -107,7 +107,7 @@ L<passphrase-encoding(7)>
 
 =head1 COPYRIGHT
 
-Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 3da051e..55e9a8b 100644 (file)
@@ -114,7 +114,7 @@ In other words, prediction resistance is currently not supported yet by the DRBG
 The derivation function is disabled during initialization by calling the
 RAND_DRBG_set() function with the RAND_DRBG_FLAG_CTR_NO_DF flag.
 For more information on the derivation function and when it can be omitted,
-see [NIST SP 800-90A Rev. 1]. Roughly speeking it can be omitted if the random
+see [NIST SP 800-90A Rev. 1]. Roughly speaking it can be omitted if the random
 source has "full entropy", i.e., contains 8 bits of entropy per byte.
 
 Even if a nonce is required, the B<get_nonce>() and B<cleanup_nonce>()
index d4b65b9..83a6cac 100644 (file)
@@ -10,7 +10,7 @@ RAND_set_rand_method, RAND_get_rand_method, RAND_OpenSSL - select RAND method
 
  RAND_METHOD *RAND_OpenSSL(void);
 
void RAND_set_rand_method(const RAND_METHOD *meth);
int RAND_set_rand_method(const RAND_METHOD *meth);
 
  const RAND_METHOD *RAND_get_rand_method(void);
 
@@ -48,8 +48,9 @@ Each pointer may be NULL if the function is not implemented.
 
 =head1 RETURN VALUES
 
-RAND_set_rand_method() returns no value. RAND_get_rand_method() and
-RAND_OpenSSL() return pointers to the respective methods.
+RAND_set_rand_method() returns 1 on success and 0 on failue.
+RAND_get_rand_method() and RAND_OpenSSL() return pointers to the respective
+methods.
 
 =head1 SEE ALSO
 
@@ -59,7 +60,7 @@ L<RAND(7)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 33d49d3..5db127f 100644 (file)
@@ -20,8 +20,7 @@ must be used to protect the RSA operation from that attack.
 
 RSA_blinding_on() turns blinding on for key B<rsa> and generates a
 random blinding factor. B<ctx> is B<NULL> or a pre-allocated and
-initialized B<BN_CTX>. The random number generator must be seeded
-prior to calling RSA_blinding_on().
+initialized B<BN_CTX>.
 
 RSA_blinding_off() turns blinding off and frees the memory used for
 the blinding factor.
@@ -34,7 +33,7 @@ RSA_blinding_off() returns no value.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index a4c078a..491ba41 100644 (file)
@@ -15,7 +15,7 @@ RSA_generate_multi_prime_key - generate RSA key pair
 Deprecated:
 
  #if OPENSSL_API_COMPAT < 0x00908000L
- RSA *RSA_generate_key(int num, unsigned long e,
+ RSA *RSA_generate_key(int bits, unsigned long e,
                        void (*callback)(int, int, void *), void *cb_arg);
  #endif
 
@@ -27,8 +27,10 @@ be seeded prior to calling RSA_generate_key_ex().
 
 RSA_generate_multi_prime_key() generates a multi-prime RSA key pair and stores
 it in the B<RSA> structure provided in B<rsa>. The number of primes is given by
-the B<primes> parameter. The pseudo-random number generator must be seeded prior
-to calling RSA_generate_multi_prime_key().
+the B<primes> parameter. The random number generator must be seeded when
+calling RSA_generate_multi_prime_key().
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
 
 The modulus size will be of length B<bits>, the number of primes to form the
 modulus will be B<primes>, and the public exponent will be B<e>. Key sizes
@@ -47,7 +49,7 @@ progress of the key generation. If B<cb> is not B<NULL>, it
 will be called as follows using the BN_GENCB_call() function
 described on the L<BN_generate_prime(3)> page.
 
-RSA_generate_prime() is similar to RSA_generate_prime_ex() but
+RSA_generate_key() is similar to RSA_generate_key_ex() but
 expects an old-style callback function; see
 L<BN_generate_prime(3)> for information on the old-style callback.
 
@@ -88,7 +90,8 @@ B<BN_GENCB_call(cb, 2, x)> is used with two different meanings.
 
 =head1 SEE ALSO
 
-L<ERR_get_error(3)>, L<RAND_bytes(3)>, L<BN_generate_prime(3)>
+L<ERR_get_error(3)>, L<RAND_bytes(3)>, L<BN_generate_prime(3)>,
+L<RAND(7)>
 
 =head1 HISTORY
 
@@ -97,7 +100,7 @@ RSA_generate_key_ex() instead.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 2092600..d0d42ce 100644 (file)
@@ -100,6 +100,8 @@ simply copy the data
 
 The random number generator must be seeded prior to calling
 RSA_padding_add_xxx().
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
 
 RSA_padding_check_xxx() verifies that the B<fl> bytes at B<f> contain
 a valid encoding for a B<rsa_len> byte RSA key in the respective
@@ -121,7 +123,7 @@ The RSA_padding_check_xxx() functions return the length of the
 recovered data, -1 on error. Error codes can be obtained by calling
 L<ERR_get_error(3)>.
 
-=head1 WARNING
+=head1 WARNINGS
 
 The result of RSA_padding_check_PKCS1_type_2() is a very sensitive
 information which can potentially be used to mount a Bleichenbacher
@@ -143,7 +145,8 @@ including PKCS1_OAEP.
 
 L<RSA_public_encrypt(3)>,
 L<RSA_private_decrypt(3)>,
-L<RSA_sign(3)>, L<RSA_verify(3)>
+L<RSA_sign(3)>, L<RSA_verify(3)>,
+L<RAND(7)>
 
 =head1 COPYRIGHT
 
index d91c688..384c482 100644 (file)
@@ -81,7 +81,7 @@ means only that the plaintext was empty.
 On error, -1 is returned; the error codes can be
 obtained by L<ERR_get_error(3)>.
 
-=head1 WARNING
+=head1 WARNINGS
 
 Decryption failures in the RSA_PKCS1_PADDING mode leak information
 which can potentially be used to mount a Bleichenbacher padding oracle
index f577e15..6e8a53b 100644 (file)
@@ -26,7 +26,10 @@ memory.
 
 B<dummy> is ignored.
 
-The random number generator must be seeded prior to calling RSA_sign_ASN1_OCTET_STRING().
+The random number generator must be seeded when calling
+RSA_sign_ASN1_OCTET_STRING().
+If the automatic seeding or reseeding of the OpenSSL CSPRNG fails due to
+external circumstances (see L<RAND(7)>), the operation will fail.
 
 RSA_verify_ASN1_OCTET_STRING() verifies that the signature B<sigbuf>
 of size B<siglen> is the DER representation of a given octet string
@@ -49,11 +52,12 @@ These functions serve no recognizable purpose.
 
 L<ERR_get_error(3)>,
 L<RAND_bytes(3)>, L<RSA_sign(3)>,
-L<RSA_verify(3)>
+L<RSA_verify(3)>,
+L<RAND(7)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 90d8674..76c4d32 100644 (file)
@@ -33,7 +33,7 @@ file syntax.
 SSL_CTX_config() and SSL_config() return 1 for success or 0 if an error
 occurred.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 If the file "config.cnf" contains the following:
 
@@ -81,7 +81,7 @@ The SSL_CTX_config() and SSL_config() functions were added in OpenSSL 1.1.0.
 
 =head1 COPYRIGHT
 
-Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index d1b3c1a..7168bd6 100644 (file)
@@ -181,7 +181,7 @@ The functions SSL_CTX_dane_set_flags(), SSL_CTX_dane_clear_flags(),
 SSL_dane_set_flags() and SSL_dane_clear_flags() return the B<flags> in effect
 before they were called.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Suppose "smtp.example.com" is the MX host of the domain "example.com", and has
 DNSSEC-validated TLSA records.
@@ -372,7 +372,7 @@ These functions were added in OpenSSL 1.1.0.
 
 =head1 COPYRIGHT
 
-Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 8b99dc3..55cddfd 100644 (file)
@@ -29,13 +29,6 @@ Typically parameters are retrieved from an B<SSL_CTX> or B<SSL> structure
 using SSL_CTX_get0_param() or SSL_get0_param() and an application modifies
 them to suit its needs: for example to add a hostname check.
 
-=head1 EXAMPLE
-
-Check hostname matches "www.foo.com" in peer certificate:
-
- X509_VERIFY_PARAM *vpm = SSL_get0_param(ssl);
- X509_VERIFY_PARAM_set1_host(vpm, "www.foo.com", 0);
-
 =head1 RETURN VALUES
 
 SSL_CTX_get0_param() and SSL_get0_param() return a pointer to an
@@ -44,6 +37,13 @@ B<X509_VERIFY_PARAM> structure.
 SSL_CTX_set1_param() and SSL_set1_param() return 1 for success and 0
 for failure.
 
+=head1 EXAMPLES
+
+Check hostname matches "www.foo.com" in peer certificate:
+
+ X509_VERIFY_PARAM *vpm = SSL_get0_param(ssl);
+ X509_VERIFY_PARAM_set1_host(vpm, "www.foo.com", 0);
+
 =head1 SEE ALSO
 
 L<X509_VERIFY_PARAM_set_flags(3)>
@@ -54,7 +54,7 @@ These functions were added in OpenSSL 1.0.2.
 
 =head1 COPYRIGHT
 
-Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index df25a6f..a6c036c 100644 (file)
@@ -94,28 +94,31 @@ The actual protocol version used will be negotiated to the highest version
 mutually supported by the client and the server.
 The supported protocols are SSLv3, TLSv1, TLSv1.1, TLSv1.2 and TLSv1.3.
 Applications should use these methods, and avoid the version-specific
-methods described below.
+methods described below, which are deprecated.
 
 =item SSLv23_method(), SSLv23_server_method(), SSLv23_client_method()
 
-Use of these functions is deprecated. They have been replaced with the above
-TLS_method(), TLS_server_method() and TLS_client_method() respectively. New
-code should use those functions instead.
+These functions do not exist anymore, they have been renamed to
+TLS_method(), TLS_server_method() and TLS_client_method() respectively.
+Currently, the old function calls are renamed to the corresponding new
+ones by preprocessor macros, to ensure that existing code which uses the
+old function names still compiles. However, using the old function names
+is deprecated and new code should call the new functions instead.
 
 =item TLSv1_2_method(), TLSv1_2_server_method(), TLSv1_2_client_method()
 
 A TLS/SSL connection established with these methods will only understand the
-TLSv1.2 protocol.
+TLSv1.2 protocol. These methods are deprecated.
 
 =item TLSv1_1_method(), TLSv1_1_server_method(), TLSv1_1_client_method()
 
 A TLS/SSL connection established with these methods will only understand the
-TLSv1.1 protocol.
+TLSv1.1 protocol.  These methods are deprecated.
 
 =item TLSv1_method(), TLSv1_server_method(), TLSv1_client_method()
 
 A TLS/SSL connection established with these methods will only understand the
-TLSv1 protocol.
+TLSv1 protocol. These methods are deprecated.
 
 =item SSLv3_method(), SSLv3_server_method(), SSLv3_client_method()
 
@@ -131,10 +134,12 @@ Currently supported protocols are DTLS 1.0 and DTLS 1.2.
 =item DTLSv1_2_method(), DTLSv1_2_server_method(), DTLSv1_2_client_method()
 
 These are the version-specific methods for DTLSv1.2.
+These methods are deprecated.
 
 =item DTLSv1_method(), DTLSv1_server_method(), DTLSv1_client_method()
 
 These are the version-specific methods for DTLSv1.
+These methods are deprecated.
 
 =back
 
index 59c6b4b..66ade10 100644 (file)
@@ -31,7 +31,7 @@ B<ssl>.
 
 SSL_CTX_set_ciphersuites() is used to configure the available TLSv1.3
 ciphersuites for B<ctx>. This is a simple colon (":") separated list of TLSv1.3
-ciphersuite names in order of perference. Valid TLSv1.3 ciphersuite names are:
+ciphersuite names in order of preference. Valid TLSv1.3 ciphersuite names are:
 
 =over 4
 
@@ -102,7 +102,7 @@ L<ciphers(1)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index dab5637..1735c62 100644 (file)
@@ -10,7 +10,7 @@ SSL_has_matching_session_id, GEN_SESSION_CB
 
  #include <openssl/ssl.h>
 
- typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id,
+ typedef int (*GEN_SESSION_CB)(SSL *ssl, unsigned char *id,
                                unsigned int *id_len);
 
  int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb);
@@ -98,7 +98,7 @@ server id given, and will fill the rest with pseudo random bytes:
  const char session_id_prefix = "www-18";
 
  #define MAX_SESSION_ID_ATTEMPTS 10
- static int generate_session_id(const SSL *ssl, unsigned char *id,
+ static int generate_session_id(SSL *ssl, unsigned char *id,
                                 unsigned int *id_len)
  {
      unsigned int count = 0;
index d832350..4036d3c 100644 (file)
@@ -42,7 +42,7 @@ OpenSSL clients will check the session id context returned by the server
 when reusing a session.
 
 The maximum length of the B<sid_ctx> is limited to
-B<SSL_MAX_SSL_SESSION_ID_LENGTH>.
+B<SSL_MAX_SID_CTX_LENGTH>.
 
 =head1 WARNINGS
 
@@ -67,7 +67,7 @@ return the following values:
 =item Z<>0
 
 The length B<sid_ctx_len> of the session id context B<sid_ctx> exceeded
-the maximum allowed length of B<SSL_MAX_SSL_SESSION_ID_LENGTH>. The error
+the maximum allowed length of B<SSL_MAX_SID_CTX_LENGTH>. The error
 is logged to the error stack.
 
 =item Z<>1
@@ -82,7 +82,7 @@ L<ssl(7)>
 
 =head1 COPYRIGHT
 
-Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 21d9ae1..1e759c3 100644 (file)
@@ -102,7 +102,7 @@ B<Server mode:> if the client did not return a certificate, the TLS/SSL
 handshake is immediately terminated with a "handshake failure" alert.
 This flag must be used together with SSL_VERIFY_PEER.
 
-B<Client mode:> ignored
+B<Client mode:> ignored (see BUGS)
 
 =item SSL_VERIFY_CLIENT_ONCE
 
@@ -112,7 +112,7 @@ renegotiation or post-authentication if a certificate was requested
 during the initial handshake. This flag must be used together with
 SSL_VERIFY_PEER.
 
-B<Client mode:> ignored
+B<Client mode:> ignored (see BUGS)
 
 =item SSL_VERIFY_POST_HANDSHAKE
 
@@ -123,7 +123,7 @@ to be configured for post-handshake peer verification before the
 handshake occurs. This flag must be used together with
 SSL_VERIFY_PEER. TLSv1.3 only; no effect on pre-TLSv1.3 connections.
 
-B<Client mode:> ignored
+B<Client mode:> ignored (see BUGS)
 
 =back
 
@@ -203,8 +203,8 @@ message is sent to the client.
 =head1 BUGS
 
 In client mode, it is not checked whether the SSL_VERIFY_PEER flag
-is set, but whether any flags are set. This can lead to
-unexpected behaviour if SSL_VERIFY_PEER and other flags are not used as
+is set, but whether any flags other than SSL_VERIFY_NONE are set. This can
+lead to unexpected behaviour if SSL_VERIFY_PEER and other flags are not used as
 required.
 
 =head1 RETURN VALUES
@@ -348,7 +348,7 @@ and SSL_set_post_handshake_auth() functions were added in OpenSSL 1.1.1.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 989c997..475f700 100644 (file)
@@ -6,7 +6,7 @@ SSL_SESSION_get0_hostname,
 SSL_SESSION_set1_hostname,
 SSL_SESSION_get0_alpn_selected,
 SSL_SESSION_set1_alpn_selected
-- get and set SNI and ALPN data ssociated with a session
+- get and set SNI and ALPN data associated with a session
 
 =head1 SYNOPSIS
 
@@ -64,7 +64,7 @@ SSL_SESSION_set1_alpn_selected() functions were added in OpenSSL 1.1.1.
 
 =head1 COPYRIGHT
 
-Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 32668a0..97320a6 100644 (file)
@@ -14,9 +14,9 @@ SSL_get_error - obtain result code for TLS/SSL I/O operation
 
 SSL_get_error() returns a result code (suitable for the C "switch"
 statement) for a preceding call to SSL_connect(), SSL_accept(), SSL_do_handshake(),
-SSL_read_ex(), SSL_read(), SSL_peek_ex(), SSL_peek(), SSL_write_ex() or
-SSL_write() on B<ssl>.  The value returned by that TLS/SSL I/O function must be
-passed to SSL_get_error() in parameter B<ret>.
+SSL_read_ex(), SSL_read(), SSL_peek_ex(), SSL_peek(), SSL_shutdown(),
+SSL_write_ex() or SSL_write() on B<ssl>.  The value returned by that TLS/SSL I/O
+function must be passed to SSL_get_error() in parameter B<ret>.
 
 In addition to B<ssl> and B<ret>, SSL_get_error() inspects the
 current thread's OpenSSL error queue.  Thus, SSL_get_error() must be
index 85768a1..e486fae 100644 (file)
@@ -25,7 +25,7 @@ implemented as a macro.
 SSL_library_init() must be called before any other action takes place.
 SSL_library_init() is not reentrant.
 
-=head1 WARNING
+=head1 WARNINGS
 
 SSL_library_init() adds ciphers and digests used directly and indirectly by
 SSL/TLS.
@@ -47,7 +47,7 @@ deprecated in OpenSSL 1.1.0 by OPENSSL_init_ssl().
 
 =head1 COPYRIGHT
 
-Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index a2c9f13..4ae9f6e 100644 (file)
@@ -71,7 +71,7 @@ applicable (as with RFC7671 DANE-EE(3)), or no trusted peername was
 matched.  Otherwise, it returns the matched peername.  To determine
 whether verification succeeded call L<SSL_get_verify_result(3)>.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Suppose "smtp.example.com" is the MX host of the domain "example.com".
 The calls below will arrange to match either the MX hostname or the
@@ -108,7 +108,7 @@ These functions were added in OpenSSL 1.1.0.
 
 =head1 COPYRIGHT
 
-Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 84eb948..a76ffbb 100644 (file)
@@ -57,7 +57,7 @@ operation is considered completed. The bytes are sent and a new write call with
 a new buffer (with the already sent bytes removed) must be started. A partial
 write is performed with the size of a message block, which is 16kB.
 
-=head1 WARNING
+=head1 WARNINGS
 
 When a write function call has to be repeated because L<SSL_get_error(3)>
 returned B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE>, it must be repeated
index f166b08..bdbf86a 100644 (file)
@@ -101,8 +101,8 @@ the operation was successful.
 
 =item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate>
 
-the issuer certificate could not be found: this occurs if the issuer certificate
-of an untrusted certificate cannot be found.
+the issuer certificate of a locally looked up certificate could not be found.
+This normally means the list of trusted certificates is not complete.
 
 =item B<X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL>
 
@@ -180,8 +180,8 @@ the root could not be found locally.
 
 =item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate>
 
-the issuer certificate of a locally looked up certificate could not be found.
-This normally means the list of trusted certificates is not complete.
+the issuer certificate could not be found: this occurs if the issuer certificate
+of an untrusted certificate cannot be found.
 
 =item B<X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate>
 
@@ -328,7 +328,7 @@ L<X509_free(3)>.
 
 =head1 COPYRIGHT
 
-Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2009-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 647ed2f..7cd661f 100644 (file)
@@ -76,7 +76,7 @@ from the corresponding B<X509_STORE>, please see
 L<X509_STORE_set_verify(3)> for more information.
 
 
-=head1 WARNING
+=head1 WARNINGS
 
 In general a verification callback should B<NOT> unconditionally return 1 in
 all circumstances because this will allow verification to succeed no matter
@@ -202,7 +202,7 @@ and X509_STORE_CTX_get_cleanup() functions were added in OpenSSL 1.1.0.
 
 =head1 COPYRIGHT
 
-Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2009-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 8ac9729..3ea5b8b 100644 (file)
@@ -55,7 +55,9 @@ operate on pointers to B<X509> objects, though.
 
 X509_STORE_add_cert() and X509_STORE_add_crl() add the respective object
 to the B<X509_STORE>'s local storage.  Untrusted objects should not be
-added in this way.
+added in this way.  The added object's reference count is incremented by one,
+hence the caller retains ownership of the object and needs to free it when it
+is no longer needed.
 
 X509_STORE_set_depth(), X509_STORE_set_flags(), X509_STORE_set_purpose(),
 X509_STORE_set_trust(), and X509_STORE_set1_param() set the default values
@@ -90,7 +92,7 @@ L<X509_STORE_get0_param(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index b3bc96e..a28c8a2 100644 (file)
@@ -23,7 +23,7 @@ X509_STORE_up_ref() increments the reference count associated with the
 X509_STORE object.
 
 X509_STORE_lock() locks the store from modification by other threads,
-X509_STORE_unlock() locks it.
+X509_STORE_unlock() unlocks it.
 
 X509_STORE_free() frees up a single X509_STORE object.
 
@@ -48,7 +48,7 @@ functions were added in OpenSSL 1.1.0.
 
 =head1 COPYRIGHT
 
-Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index f45467c..7593dea 100644 (file)
@@ -346,7 +346,7 @@ If CRLs checking is enable CRLs are expected to be available in the
 corresponding B<X509_STORE> structure. No attempt is made to download
 CRLs from the CRL distribution points extension.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Enable CRL checking when performing certificate verification during SSL
 connections associated with an B<SSL_CTX> structure B<ctx>:
@@ -376,7 +376,7 @@ The X509_VERIFY_PARAM_get_hostflags() function was added in OpenSSL 1.1.0i.
 
 =head1 COPYRIGHT
 
-Copyright 2009-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2009-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/doc/man3/X509_cmp.pod b/doc/man3/X509_cmp.pod
new file mode 100644 (file)
index 0000000..3cb16b2
--- /dev/null
@@ -0,0 +1,80 @@
+=pod
+
+=head1 NAME
+
+X509_cmp, X509_NAME_cmp,
+X509_issuer_and_serial_cmp, X509_issuer_name_cmp, X509_subject_name_cmp,
+X509_CRL_cmp, X509_CRL_match
+- compare X509 certificates and related values
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ int X509_cmp(const X509 *a, const X509 *b);
+ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+ int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
+ int X509_issuer_name_cmp(const X509 *a, const X509 *b);
+ int X509_subject_name_cmp(const X509 *a, const X509 *b);
+ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+ int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
+
+=head1 DESCRIPTION
+
+This set of functions are used to compare X509 objects, including X509
+certificates, X509 CRL objects and various values in an X509 certificate.
+
+The X509_cmp() function compares two B<X509> objects indicated by parameters
+B<a> and B<b>. The comparison is based on the B<memcmp> result of the hash
+values of two B<X509> objects and the canonical (DER) encoding values.
+
+The X509_NAME_cmp() function compares two B<X509_NAME> objects indicated by
+parameters B<a> and B<b>. The comparison is based on the B<memcmp> result of
+the canonical (DER) encoding values of the two objects. L<i2d_X509_NAME(3)>
+has a more detailed description of the DER encoding of the B<X509_NAME> structure.
+
+The X509_issuer_and_serial_cmp() function compares the serial number and issuer
+values in the given B<X509> objects B<a> and B<b>.
+
+The X509_issuer_name_cmp(), X509_subject_name_cmp() and X509_CRL_cmp() functions
+are effectively wrappers of the X509_NAME_cmp() function. These functions compare
+issuer names and subject names of the X<509> objects, or issuers of B<X509_CRL>
+objects, respectively.
+
+The X509_CRL_match() function compares two B<X509_CRL> objects. Unlike the
+X509_CRL_cmp() function, this function compares the whole CRL content instead
+of just the issuer name.
+
+=head1 RETURN VALUES
+
+Like common memory comparison functions, the B<X509> comparison functions return
+an integer less than, equal to, or greater than zero if object B<a> is found to
+be less than, to match, or be greater than object B<b>, respectively.
+
+X509_NAME_cmp(), X509_issuer_and_serial_cmp(), X509_issuer_name_cmp(),
+X509_subject_name_cmp() and X509_CRL_cmp() may return B<-2> to indicate an error.
+
+=head1 NOTES
+
+These functions in fact utilize the underlying B<memcmp> of the C library to do
+the comparison job. Data to be compared varies from DER encoding data, hash
+value or B<ASN1_STRING>. The sign of the comparison can be used to order the
+objects but it does not have a special meaning in some cases.
+
+X509_NAME_cmp() and wrappers utilize the value B<-2> to indicate errors in some
+circumstances, which could cause confusion for the applications.
+
+=head1 SEE ALSO
+
+L<i2d_X509_NAME(3)>, L<i2d_X509(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index fc4ebbb..2dfe2ef 100644 (file)
@@ -4,6 +4,8 @@
 
 X509_get0_subject_key_id,
 X509_get0_authority_key_id,
+X509_get0_authority_issuer,
+X509_get0_authority_serial,
 X509_get_pathlen,
 X509_get_extension_flags,
 X509_get_key_usage,
@@ -22,6 +24,8 @@ X509_get_proxy_pathlen - retrieve certificate extension data
  uint32_t X509_get_extended_key_usage(X509 *x);
  const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x);
  const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x);
+ const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x);
+ const ASN1_INTEGER *X509_get0_authority_serial(X509 *x);
  void X509_set_proxy_flag(X509 *x);
  void X509_set_proxy_pathlen(int l);
  long X509_get_proxy_pathlen(X509 *x);
@@ -115,6 +119,14 @@ X509_get0_authority_key_id() returns an internal pointer to the authority key
 identifier of B<x> as an B<ASN1_OCTET_STRING> or B<NULL> if the extension
 is not present or cannot be parsed.
 
+X509_get0_authority_issuer() returns an internal pointer to the authority
+certificate issuer of B<x> as a stack of B<GENERAL_NAME> structures or
+B<NULL> if the extension is not present or cannot be parsed.
+
+X509_get0_authority_serial() returns an internal pointer to the authority
+certificate serial number of B<x> as an B<ASN1_INTEGER> or B<NULL> if the
+extension is not present or cannot be parsed.
+
 X509_set_proxy_flag() marks the certificate with the B<EXFLAG_PROXY> flag.
 This is for the users who need to mark non-RFC3820 proxy certificates as
 such, as OpenSSL only detects RFC3820 compliant ones.
@@ -171,7 +183,7 @@ X509_get_proxy_pathlen() were added in OpenSSL 1.1.0.
 
 =head1 COPYRIGHT
 
-Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 3d50f5d..e36270f 100644 (file)
@@ -53,6 +53,7 @@ d2i_DSA_PUBKEY_bio,
 d2i_DSA_PUBKEY_fp,
 d2i_DSA_SIG,
 d2i_DSAparams,
+d2i_ECDSA_SIG,
 d2i_ECPKParameters,
 d2i_ECParameters,
 d2i_ECPrivateKey,
@@ -229,6 +230,7 @@ i2d_DSA_PUBKEY_bio,
 i2d_DSA_PUBKEY_fp,
 i2d_DSA_SIG,
 i2d_DSAparams,
+i2d_ECDSA_SIG,
 i2d_ECPKParameters,
 i2d_ECParameters,
 i2d_ECPrivateKey,
@@ -472,6 +474,10 @@ Represents a DSA public key using a B<SubjectPublicKeyInfo> structure.
 Use a non-standard OpenSSL format and should be avoided; use B<DSA_PUBKEY>,
 B<PEM_write_PrivateKey(3)>, or similar instead.
 
+=item B<ECDSA_SIG>
+
+Represents an ECDSA signature.
+
 =item B<RSAPublicKey>
 
 Represents a PKCS#1 RSA public key structure.
@@ -500,8 +506,8 @@ Represents the B<DigestInfo> structure defined in PKCS#1 and PKCS#7.
 
 d2i_TYPE(), d2i_TYPE_bio() and d2i_TYPE_fp() return a valid B<TYPE> structure
 or B<NULL> if an error occurs.  If the "reuse" capability has been used with
-a valid structure being passed in via B<a>, then the object is not freed in
-the event of error but may be in a potentially invalid or inconsistent state.
+a valid structure being passed in via B<a>, then the object is freed in
+the event of error and B<*a> is set to NULL.
 
 i2d_TYPE() returns the number of bytes successfully encoded or a negative
 value if an error occurs.
@@ -582,9 +588,13 @@ happen.
 =head1 BUGS
 
 In some versions of OpenSSL the "reuse" behaviour of d2i_TYPE() when
-B<*px> is valid is broken and some parts of the reused structure may
-persist if they are not present in the new one. As a result the use
-of this "reuse" behaviour is strongly discouraged.
+B<*a> is valid is broken and some parts of the reused structure may
+persist if they are not present in the new one. Additionally, in versions of
+OpenSSL prior to 1.1.0, when the "reuse" behaviour is used and an error occurs
+the behaviour is inconsistent. Some functions behaved as described here, while
+some did not free B<*a> on error and did not set B<*a> to NULL.
+
+As a result of the above issues the "reuse" behaviour is strongly discouraged.
 
 i2d_TYPE() will not return an error in many versions of OpenSSL,
 if mandatory fields are not initialized due to a programming error
index a35b4cc..803b12b 100644 (file)
@@ -483,7 +483,7 @@ For example:
 
  basicConstraints=critical,DER:00:01:02:03
 
-=head1 WARNING
+=head1 WARNINGS
 
 There is no guarantee that a specific implementation will process a given
 extension. It may therefore be sometimes possible to use certificates for
@@ -493,7 +493,6 @@ not recognize or honour the values of the relevant extensions.
 The DER and ASN1 options should be used with caution. It is possible to create
 totally invalid extensions if they are not used carefully.
 
-
 =head1 NOTES
 
 If an extension is multi-value and a field value must contain a comma the long
@@ -535,7 +534,7 @@ L<ASN1_generate_nconf(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2004-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 3f54217..6442e0e 100644 (file)
@@ -53,7 +53,7 @@ Ed25519 and Ed448 can be tested within L<speed(1)> application since version 1.1
 Valid algorithm names are B<ed25519>, B<ed448> and B<eddsa>. If B<eddsa> is
 specified, then both Ed25519 and Ed448 are benchmarked.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example generates an B<ED25519> private key and writes it to standard
 output in PEM format:
@@ -77,7 +77,7 @@ L<EVP_DigestVerifyInit(3)>,
 
 =head1 COPYRIGHT
 
-Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 971b3cd..7ce44ad 100644 (file)
@@ -28,6 +28,12 @@ As a normal application developer, you do not have to worry about any details,
 just use L<RAND_bytes(3)> to obtain random data.
 Having said that, there is one important rule to obey: Always check the error
 return value of L<RAND_bytes(3)> and do not take randomness for granted.
+Although (re-)seeding is automatic, it can fail because no trusted random source
+is available or the trusted source(s) temporarily fail to provide sufficient
+random seed material.
+In this case the CSPRNG enters an error state and ceases to provide output,
+until it is able to recover from the error by reseeding itself.
+For more details on reseeding and error recovery, see L<RAND_DRBG(7)>.
 
 For values that should remain secret, you can use L<RAND_priv_bytes(3)>
 instead.
@@ -71,7 +77,7 @@ L<RAND_DRBG(7)>
 
 =head1 COPYRIGHT
 
-Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 029dc73..c8fceff 100644 (file)
@@ -41,7 +41,7 @@ done by calling:
 And normally there is no need to pass a B<pctx> parameter to EVP_DigestSignInit()
 or EVP_DigestVerifyInit() in such a scenario.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example demonstrates the calling sequence for using an B<EVP_PKEY> to verify
 a message with the SM2 signature algorithm and the SM3 hash algorithm:
@@ -69,7 +69,7 @@ L<EVP_MD_CTX_set_pkey_ctx(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 7cb6ff6..4851f8a 100644 (file)
@@ -37,7 +37,7 @@ X25519 or X448 public keys can be set directly using
 L<EVP_PKEY_new_raw_public_key(3)> or loaded from a SubjectPublicKeyInfo
 structure in a PEM file using L<PEM_read_bio_PUBKEY(3)> (or similar function).
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example generates an B<X25519> private key and writes it to standard
 output in PEM format:
@@ -64,7 +64,7 @@ L<EVP_PKEY_derive_set_peer(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 45ef2f7..23b231b 100644 (file)
@@ -52,7 +52,7 @@ pointer to a BIO_METHOD. There is a naming convention for such functions:
 a source/sink BIO is normally called BIO_s_*() and a filter BIO
 BIO_f_*();
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 Create a memory BIO:
 
@@ -76,7 +76,7 @@ L<BIO_should_retry(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 94ff3ab..a005133 100644 (file)
@@ -38,7 +38,7 @@ A context for scrypt can be obtained by calling:
 The output length of an scrypt key derivation is specified via the
 length parameter to the L<EVP_PKEY_derive(3)> function.
 
-=head1 EXAMPLE
+=head1 EXAMPLES
 
 This example derives a 64-byte long test vector using scrypt using the password
 "password", salt "NaCl" and N = 1024, r = 8, p = 16.
@@ -105,7 +105,7 @@ L<EVP_PKEY_derive(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the OpenSSL license (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/e_os.h b/e_os.h
index e9ce6c9..858bc40 100644 (file)
--- a/e_os.h
+++ b/e_os.h
  * default, we will try to read at least one of these files
  */
 #  define DEVRANDOM "/dev/urandom", "/dev/random", "/dev/hwrng", "/dev/srandom"
-#  ifdef __linux
-#   define DEVRANDOM_WAIT "/dev/random"
+#  if defined(__linux) && !defined(__ANDROID__)
+#   ifndef DEVRANDOM_WAIT
+#    define DEVRANDOM_WAIT   "/dev/random"
+#   endif
+/*
+ * Linux kernels 4.8 and later changes how their random device works and there
+ * is no reliable way to tell that /dev/urandom has been seeded -- getentropy(2)
+ * should be used instead.
+ */
+#   ifndef DEVRANDOM_SAFE_KERNEL
+#    define DEVRANDOM_SAFE_KERNEL        4, 8
+#   endif
+/*
+ * Some operating systems do not permit select(2) on their random devices,
+ * defining this to zero will force the used of read(2) to extract one byte
+ * from /dev/random.
+ */
+#   ifndef DEVRANDM_WAIT_USE_SELECT
+#    define DEVRANDM_WAIT_USE_SELECT     1
+#   endif
+/*
+ * Define the shared memory identifier used to indicate if the operating
+ * system has properly seeded the DEVRANDOM source.
+ */
+#   ifndef OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID
+#    define OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID 114
+#   endif
+
 #  endif
 # endif
 # if !defined(OPENSSL_NO_EGD) && !defined(DEVRANDOM_EGD)
index df173ea..1db7719 100644 (file)
@@ -2,8 +2,9 @@ IF[{- !$disabled{"engine"} -}]
 
   IF[{- $disabled{"dynamic-engine"} -}]
     LIBS=../libcrypto
-    SOURCE[../libcrypto]=\
-            e_padlock.c {- $target{padlock_asm_src} -}
+    IF[{- !$disabled{hw} && !$disabled{'hw-padlock'} -}]
+      SOURCE[../libcrypto]= e_padlock.c {- $target{padlock_asm_src} -}
+    ENDIF
     IF[{- !$disabled{capieng} -}]
       SOURCE[../libcrypto]=e_capi.c
     ENDIF
@@ -11,10 +12,12 @@ IF[{- !$disabled{"engine"} -}]
       SOURCE[../libcrypto]=e_afalg.c
     ENDIF
   ELSE
-    ENGINES=padlock
-    SOURCE[padlock]=e_padlock.c {- $target{padlock_asm_src} -}
-    DEPEND[padlock]=../libcrypto
-    INCLUDE[padlock]=../include
+    IF[{- !$disabled{hw} && !$disabled{'hw-padlock'} -}]
+      ENGINES=padlock
+      SOURCE[padlock]=e_padlock.c {- $target{padlock_asm_src} -}
+      DEPEND[padlock]=../libcrypto
+      INCLUDE[padlock]=../include
+    ENDIF
     IF[{- !$disabled{capieng} -}]
       ENGINES=capi
       SOURCE[capi]=e_capi.c
index f09c396..7f62d77 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -63,9 +63,6 @@ void engine_load_afalg_int(void)
 # define ALG_OP_TYPE     unsigned int
 # define ALG_OP_LEN      (sizeof(ALG_OP_TYPE))
 
-#define ALG_MAX_SALG_NAME       64
-#define ALG_MAX_SALG_TYPE       14
-
 # ifdef OPENSSL_NO_DYNAMIC_ENGINE
 void engine_load_afalg_int(void);
 # endif
@@ -371,10 +368,8 @@ static int afalg_create_sk(afalg_ctx *actx, const char *ciphertype,
 
     memset(&sa, 0, sizeof(sa));
     sa.salg_family = AF_ALG;
-    strncpy((char *) sa.salg_type, ciphertype, ALG_MAX_SALG_TYPE);
-    sa.salg_type[ALG_MAX_SALG_TYPE-1] = '\0';
-    strncpy((char *) sa.salg_name, ciphername, ALG_MAX_SALG_NAME);
-    sa.salg_name[ALG_MAX_SALG_NAME-1] = '\0';
+    OPENSSL_strlcpy((char *) sa.salg_type, ciphertype, sizeof(sa.salg_type));
+    OPENSSL_strlcpy((char *) sa.salg_name, ciphername, sizeof(sa.salg_name));
 
     actx->bfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
     if (actx->bfd == -1) {
@@ -502,7 +497,7 @@ static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     int ciphertype;
     int ret;
     afalg_ctx *actx;
-    char ciphername[ALG_MAX_SALG_NAME];
+    const char *ciphername;
 
     if (ctx == NULL || key == NULL) {
         ALG_WARN("%s(%d): Null Parameter\n", __FILE__, __LINE__);
@@ -525,14 +520,13 @@ static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     case NID_aes_128_cbc:
     case NID_aes_192_cbc:
     case NID_aes_256_cbc:
-        strncpy(ciphername, "cbc(aes)", ALG_MAX_SALG_NAME);
+        ciphername = "cbc(aes)";
         break;
     default:
         ALG_WARN("%s(%d): Unsupported Cipher type %d\n", __FILE__, __LINE__,
                  ciphertype);
         return 0;
     }
-    ciphername[ALG_MAX_SALG_NAME-1]='\0';
 
     if (ALG_AES_IV_LEN != EVP_CIPHER_CTX_iv_length(ctx)) {
         ALG_WARN("%s(%d): Unsupported IV length :%d\n", __FILE__, __LINE__,
index cde30f4..0193a65 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2014-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -213,18 +213,72 @@ static ossl_inline unsigned char constant_time_eq_int_8(int a, int b)
     return constant_time_eq_8((unsigned)(a), (unsigned)(b));
 }
 
+/*
+ * Returns the value unmodified, but avoids optimizations.
+ * The barriers prevent the compiler from narrowing down the
+ * possible value range of the mask and ~mask in the select
+ * statements, which avoids the recognition of the select
+ * and turning it into a conditional load or branch.
+ */
+static ossl_inline unsigned int value_barrier(unsigned int a)
+{
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
+    unsigned int r;
+    __asm__("" : "=r"(r) : "0"(a));
+#else
+    volatile unsigned int r = a;
+#endif
+    return r;
+}
+
+/* Convenience method for uint32_t. */
+static ossl_inline uint32_t value_barrier_32(uint32_t a)
+{
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
+    uint32_t r;
+    __asm__("" : "=r"(r) : "0"(a));
+#else
+    volatile uint32_t r = a;
+#endif
+    return r;
+}
+
+/* Convenience method for uint64_t. */
+static ossl_inline uint64_t value_barrier_64(uint64_t a)
+{
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
+    uint64_t r;
+    __asm__("" : "=r"(r) : "0"(a));
+#else
+    volatile uint64_t r = a;
+#endif
+    return r;
+}
+
+/* Convenience method for size_t. */
+static ossl_inline size_t value_barrier_s(size_t a)
+{
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
+    size_t r;
+    __asm__("" : "=r"(r) : "0"(a));
+#else
+    volatile size_t r = a;
+#endif
+    return r;
+}
+
 static ossl_inline unsigned int constant_time_select(unsigned int mask,
                                                      unsigned int a,
                                                      unsigned int b)
 {
-    return (mask & a) | (~mask & b);
+    return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
 }
 
 static ossl_inline size_t constant_time_select_s(size_t mask,
                                                  size_t a,
                                                  size_t b)
 {
-    return (mask & a) | (~mask & b);
+    return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b);
 }
 
 static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
@@ -249,13 +303,13 @@ static ossl_inline int constant_time_select_int_s(size_t mask, int a, int b)
 static ossl_inline uint32_t constant_time_select_32(uint32_t mask, uint32_t a,
                                                     uint32_t b)
 {
-    return (mask & a) | (~mask & b);
+    return (value_barrier_32(mask) & a) | (value_barrier_32(~mask) & b);
 }
 
 static ossl_inline uint64_t constant_time_select_64(uint64_t mask, uint64_t a,
                                                     uint64_t b)
 {
-    return (mask & a) | (~mask & b);
+    return (value_barrier_64(mask) & a) | (value_barrier_64(~mask) & b);
 }
 
 /*
index b4d76d5..23e17e5 100644 (file)
@@ -80,6 +80,7 @@ extern unsigned int OPENSSL_ia32cap_P[];
 void OPENSSL_showfatal(const char *fmta, ...);
 void crypto_cleanup_all_ex_data_int(void);
 int openssl_init_fork_handlers(void);
+int openssl_get_fork_id(void);
 
 char *ossl_safe_getenv(const char *name);
 
index 0edf277..5f4511c 100644 (file)
@@ -11,7 +11,9 @@
 #ifndef HEADER_DSOERR_H
 # define HEADER_DSOERR_H
 
-# include <openssl/opensslconf.h>
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
 
 # ifdef  __cplusplus
 extern "C"
index d2364c6..6e1a840 100644 (file)
@@ -105,7 +105,7 @@ static __inline int CRYPTO_DOWN_REF(volatile int *val, int *ret, void *lock)
 #    if _WIN32_WCE >= 0x600
       extern long __cdecl _InterlockedExchangeAdd(long volatile*, long);
 #    else
-      // under Windows CE we still have old-style Interlocked* functions
+      /* under Windows CE we still have old-style Interlocked* functions */
       extern long __cdecl InterlockedExchangeAdd(long volatile*, long);
 #     define _InterlockedExchangeAdd InterlockedExchangeAdd
 #    endif
index 8a25d04..8f8aa6e 100644 (file)
@@ -72,7 +72,7 @@
  * function defined via DEFINE_ONCE_STATIC where both functions use the same
  * CRYPTO_ONCE object to synchronise. Where an alternative initialiser function
  * is used only one of the primary or the alternative initialiser function will
- * ever be called - and that function will be called exactly once. Definitition
+ * ever be called - and that function will be called exactly once. Definition
  * of an alternative initialiser function MUST occur AFTER the definition of the
  * primary initialiser function.
  *
index d41ebb3..cc30162 100644 (file)
@@ -18,7 +18,7 @@
  * if (var == NOT_YET_INITIALIZED)
  *     var = function_returning_same_value();
  *
- * This does work provided that loads and stores are single-instuction
+ * This does work provided that loads and stores are single-instruction
  * operations (and integer ones are on *all* supported platforms), but
  * it upsets Thread Sanitizer. Suggested solution is
  *
index 5a91126..faed5a5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_ASN1ERR_H
 # define HEADER_ASN1ERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 5497ba7..91afbbb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_ASYNCERR_H
 # define HEADER_ASYNCERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 2888b42..e1fddfb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 # include <openssl/crypto.h>
 # include <openssl/bioerr.h>
 
-# ifndef OPENSSL_NO_SCTP
-#  include <openssl/e_os2.h>
-# endif
-
 #ifdef  __cplusplus
 extern "C" {
 #endif
index f119a59..46e2c96 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_BIOERR_H
 # define HEADER_BIOERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 8a022cc..9f3c7cf 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_BNERR_H
 # define HEADER_BNERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 3aee132..04f6ff7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_BUFERR_H
 # define HEADER_BUFERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index ddf37e5..c762796 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -284,8 +284,6 @@ int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
 void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
                                     int lastpos, int type);
 
-# ifdef HEADER_X509V3_H
-
 int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
 CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
                                                int allorfirst,
@@ -298,7 +296,6 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
                                     int *pallorfirst,
                                     STACK_OF(GENERAL_NAMES) **plist,
                                     STACK_OF(GENERAL_NAMES) **prto);
-# endif
 int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
                                     X509_ALGOR **palg,
                                     ASN1_OCTET_STRING **pukm);
index 3f8ae26..7dbc13d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_CMSERR_H
 # define HEADER_CMSERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_CMS
@@ -101,6 +105,7 @@ int ERR_load_CMS_strings(void);
 #  define CMS_F_CMS_SIGNERINFO_VERIFY_CERT                 153
 #  define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT              154
 #  define CMS_F_CMS_SIGN_RECEIPT                           163
+#  define CMS_F_CMS_SI_CHECK_ATTRIBUTES                    183
 #  define CMS_F_CMS_STREAM                                 155
 #  define CMS_F_CMS_UNCOMPRESS                             156
 #  define CMS_F_CMS_VERIFY                                 157
@@ -110,6 +115,7 @@ int ERR_load_CMS_strings(void);
  * CMS reason codes.
  */
 #  define CMS_R_ADD_SIGNER_ERROR                           99
+#  define CMS_R_ATTRIBUTE_ERROR                            161
 #  define CMS_R_CERTIFICATE_ALREADY_PRESENT                175
 #  define CMS_R_CERTIFICATE_HAS_NO_KEYID                   160
 #  define CMS_R_CERTIFICATE_VERIFY_ERROR                   100
index edea63a..90231e9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_COMPERR_H
 # define HEADER_COMPERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_COMP
index d1c92f4..32b9229 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_CONFERR_H
 # define HEADER_CONFERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 10723d0..3db5a4e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_CRYPTOERR_H
 # define HEADER_CRYPTOERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
-
-# include <openssl/symhacks.h>
-
 int ERR_load_CRYPTO_strings(void);
 
 /*
index 764e1a2..feb7bc5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_CTERR_H
 # define HEADER_CTERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_CT
index 81e73f7..916b3be 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_DHERR_H
 # define HEADER_DHERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_DH
index d94f97b..495a1ac 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_DSAERR_H
 # define HEADER_DSAERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_DSA
@@ -57,6 +61,7 @@ int ERR_load_DSA_strings(void);
 #  define DSA_R_INVALID_DIGEST_TYPE                        106
 #  define DSA_R_INVALID_PARAMETERS                         112
 #  define DSA_R_MISSING_PARAMETERS                         101
+#  define DSA_R_MISSING_PRIVATE_KEY                        111
 #  define DSA_R_MODULUS_TOO_LARGE                          103
 #  define DSA_R_NO_PARAMETERS_SET                          107
 #  define DSA_R_PARAMETER_ENCODING_ERROR                   105
index 347cfb6..5af9ebd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
@@ -142,7 +142,7 @@ const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
  */
 int EC_METHOD_get_field_type(const EC_METHOD *meth);
 
-/** Sets the generator and it's order/cofactor of a EC_GROUP object.
+/** Sets the generator and its order/cofactor of a EC_GROUP object.
  *  \param  group      EC_GROUP object
  *  \param  generator  EC_POINT object with the generator.
  *  \param  order      the order of the group generated by the generator.
@@ -1138,7 +1138,8 @@ void ECDSA_SIG_free(ECDSA_SIG *sig);
  *  (*pp += length of the DER encoded signature)).
  *  \param  sig  pointer to the ECDSA_SIG object
  *  \param  pp   pointer to a unsigned char pointer for the output or NULL
- *  \return the length of the DER encoded ECDSA_SIG object or 0
+ *  \return the length of the DER encoded ECDSA_SIG object or a negative value
+ *          on error
  */
 int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
 
index be313d2..f7b9183 100644 (file)
 #ifndef HEADER_ECERR_H
 # define HEADER_ECERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_EC
index b4c036b..05e84bd 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_ENGINEERR_H
 # define HEADER_ENGINEERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_ENGINE
index dd1117d..545654a 100644 (file)
@@ -260,6 +260,8 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
 # define         EVP_CIPH_RAND_KEY               0x200
 /* cipher has its own additional copying logic */
 # define         EVP_CIPH_CUSTOM_COPY            0x400
+/* Don't use standard iv length function */
+# define         EVP_CIPH_CUSTOM_IV_LENGTH       0x800
 /* Allow use default ASN1 get/set iv */
 # define         EVP_CIPH_FLAG_DEFAULT_ASN1      0x1000
 /* Buffer length in bits not bytes: CFB1 mode only */
@@ -349,6 +351,8 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
 /* Set the input buffer lengths to use for a pipelined operation */
 # define         EVP_CTRL_SET_PIPELINE_INPUT_LENS        0x24
 
+# define         EVP_CTRL_GET_IVLEN                      0x25
+
 /* Padding modes */
 #define EVP_PADDING_PKCS7       1
 #define EVP_PADDING_ISO7816_4   2
index 84f03eb..6a651f5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_EVPERR_H
 # define HEADER_EVPERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
@@ -20,11 +24,14 @@ int ERR_load_EVP_strings(void);
  * EVP function codes.
  */
 # define EVP_F_AESNI_INIT_KEY                             165
+# define EVP_F_AESNI_XTS_INIT_KEY                         207
 # define EVP_F_AES_GCM_CTRL                               196
 # define EVP_F_AES_INIT_KEY                               133
 # define EVP_F_AES_OCB_CIPHER                             169
 # define EVP_F_AES_T4_INIT_KEY                            178
+# define EVP_F_AES_T4_XTS_INIT_KEY                        208
 # define EVP_F_AES_WRAP_CIPHER                            170
+# define EVP_F_AES_XTS_INIT_KEY                           209
 # define EVP_F_ALG_MODULE_INIT                            177
 # define EVP_F_ARIA_CCM_INIT_KEY                          175
 # define EVP_F_ARIA_GCM_CTRL                              197
@@ -115,6 +122,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_F_PKEY_SET_TYPE                              158
 # define EVP_F_RC2_MAGIC_TO_METH                          109
 # define EVP_F_RC5_CTRL                                   125
+# define EVP_F_R_32_12_16_INIT_KEY                        242
 # define EVP_F_S390X_AES_GCM_CTRL                         201
 # define EVP_F_UPDATE                                     173
 
@@ -124,6 +132,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_R_AES_KEY_SETUP_FAILED                       143
 # define EVP_R_ARIA_KEY_SETUP_FAILED                      176
 # define EVP_R_BAD_DECRYPT                                100
+# define EVP_R_BAD_KEY_LENGTH                             195
 # define EVP_R_BUFFER_TOO_SMALL                           155
 # define EVP_R_CAMELLIA_KEY_SETUP_FAILED                  157
 # define EVP_R_CIPHER_PARAMETER_ERROR                     122
@@ -190,5 +199,6 @@ int ERR_load_EVP_strings(void);
 # define EVP_R_UNSUPPORTED_SALT_TYPE                      126
 # define EVP_R_WRAP_MODE_NOT_ALLOWED                      170
 # define EVP_R_WRONG_FINAL_BLOCK_LENGTH                   109
+# define EVP_R_XTS_DUPLICATED_KEYS                        183
 
 #endif
index 6437c27..3f51bd0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_KDFERR_H
 # define HEADER_KDFERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 02308df..02e166f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_OBJERR_H
 # define HEADER_OBJERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 7d93b12..8dd9e01 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_OCSPERR_H
 # define HEADER_OCSPERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_OCSP
index bdf44d4..c28e632 100644 (file)
@@ -39,8 +39,8 @@ extern "C" {
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-# define OPENSSL_VERSION_NUMBER  0x1010103fL
-# define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.1c  28 May 2019"
+# define OPENSSL_VERSION_NUMBER  0x1010104fL
+# define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.1d  10 Sep 2019"
 
 /*-
  * The macros below are to be used for shared library (.so, .dll, ...)
index cd61b82..0c45918 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_PEMERR_H
 # define HEADER_PEMERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index c7184ff..eff5eb2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_PKCS12ERR_H
 # define HEADER_PKCS12ERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 0ba418d..02e0299 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_PKCS7ERR_H
 # define HEADER_PKCS7ERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 599a2a1..70d1a17 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -11,6 +11,8 @@
 #ifndef HEADER_RANDERR_H
 # define HEADER_RANDERR_H
 
+# include <openssl/symhacks.h>
+
 # ifdef  __cplusplus
 extern "C"
 # endif
@@ -42,6 +44,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_F_RAND_POOL_ADD_END                         114
 # define RAND_F_RAND_POOL_ATTACH                          124
 # define RAND_F_RAND_POOL_BYTES_NEEDED                    115
+# define RAND_F_RAND_POOL_GROW                            125
 # define RAND_F_RAND_POOL_NEW                             116
 # define RAND_F_RAND_WRITE_FILE                           112
 
index d5bc01c..59b15e1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_RSAERR_H
 # define HEADER_RSAERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
@@ -126,6 +130,7 @@ int ERR_load_RSA_strings(void);
 # define RSA_R_KEY_PRIME_NUM_INVALID                      165
 # define RSA_R_KEY_SIZE_TOO_SMALL                         120
 # define RSA_R_LAST_OCTET_INVALID                         134
+# define RSA_R_MISSING_PRIVATE_KEY                        179
 # define RSA_R_MGF1_DIGEST_NOT_ALLOWED                    152
 # define RSA_R_MODULUS_TOO_LARGE                          105
 # define RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R            168
index f93dc68..6724ccf 100644 (file)
@@ -1364,24 +1364,24 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st))
 # define SSL_CTX_set1_chain_cert_store(ctx,st) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st))
-# define SSL_set0_chain(ctx,sk) \
-        SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)(sk))
-# define SSL_set1_chain(ctx,sk) \
-        SSL_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)(sk))
-# define SSL_add0_chain_cert(ctx,x509) \
-        SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509))
-# define SSL_add1_chain_cert(ctx,x509) \
-        SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)(x509))
-# define SSL_get0_chain_certs(ctx,px509) \
-        SSL_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
-# define SSL_clear_chain_certs(ctx) \
-        SSL_set0_chain(ctx,NULL)
+# define SSL_set0_chain(s,sk) \
+        SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk))
+# define SSL_set1_chain(s,sk) \
+        SSL_ctrl(s,SSL_CTRL_CHAIN,1,(char *)(sk))
+# define SSL_add0_chain_cert(s,x509) \
+        SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,0,(char *)(x509))
+# define SSL_add1_chain_cert(s,x509) \
+        SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,1,(char *)(x509))
+# define SSL_get0_chain_certs(s,px509) \
+        SSL_ctrl(s,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
+# define SSL_clear_chain_certs(s) \
+        SSL_set0_chain(s,NULL)
 # define SSL_build_cert_chain(s, flags) \
         SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
-# define SSL_select_current_cert(ctx,x509) \
-        SSL_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509))
-# define SSL_set_current_cert(ctx,op) \
-        SSL_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
+# define SSL_select_current_cert(s,x509) \
+        SSL_ctrl(s,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509))
+# define SSL_set_current_cert(s,op) \
+        SSL_ctrl(s,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
 # define SSL_set0_verify_cert_store(s,st) \
         SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st))
 # define SSL_set1_verify_cert_store(s,st) \
@@ -1390,34 +1390,34 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
         SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st))
 # define SSL_set1_chain_cert_store(s,st) \
         SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st))
-# define SSL_get1_groups(ctx, s) \
-        SSL_ctrl(ctx,SSL_CTRL_GET_GROUPS,0,(char *)(s))
+# define SSL_get1_groups(s, glist) \
+        SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist))
 # define SSL_CTX_set1_groups(ctx, glist, glistlen) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist))
 # define SSL_CTX_set1_groups_list(ctx, s) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(s))
-# define SSL_set1_groups(ctx, glist, glistlen) \
-        SSL_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist))
-# define SSL_set1_groups_list(ctx, s) \
-        SSL_ctrl(ctx,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(s))
+# define SSL_set1_groups(s, glist, glistlen) \
+        SSL_ctrl(s,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist))
+# define SSL_set1_groups_list(s, str) \
+        SSL_ctrl(s,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(str))
 # define SSL_get_shared_group(s, n) \
         SSL_ctrl(s,SSL_CTRL_GET_SHARED_GROUP,n,NULL)
 # define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist))
 # define SSL_CTX_set1_sigalgs_list(ctx, s) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(s))
-# define SSL_set1_sigalgs(ctx, slist, slistlen) \
-        SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist))
-# define SSL_set1_sigalgs_list(ctx, s) \
-        SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(s))
+# define SSL_set1_sigalgs(s, slist, slistlen) \
+        SSL_ctrl(s,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist))
+# define SSL_set1_sigalgs_list(s, str) \
+        SSL_ctrl(s,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(str))
 # define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist))
 # define SSL_CTX_set1_client_sigalgs_list(ctx, s) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(s))
-# define SSL_set1_client_sigalgs(ctx, slist, slistlen) \
-        SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,clistlen,(int *)(slist))
-# define SSL_set1_client_sigalgs_list(ctx, s) \
-        SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(s))
+# define SSL_set1_client_sigalgs(s, slist, slistlen) \
+        SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist))
+# define SSL_set1_client_sigalgs_list(s, str) \
+        SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(str))
 # define SSL_get0_certificate_types(s, clist) \
         SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)(clist))
 # define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \
index a50a075..3d6850d 100644 (file)
 #ifndef HEADER_SSLERR_H
 # define HEADER_SSLERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 7b43e8b..a40a733 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -85,7 +85,7 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx);
 int OSSL_STORE_eof(OSSL_STORE_CTX *ctx);
 
 /*
- * Check if an error occured
+ * Check if an error occurred
  * Returns 1 if it did, 0 otherwise.
  */
 int OSSL_STORE_error(OSSL_STORE_CTX *ctx);
@@ -117,7 +117,7 @@ int OSSL_STORE_close(OSSL_STORE_CTX *ctx);
  * Functions to generate OSSL_STORE_INFOs, one function for each type we
  * support having in them, as well as a generic constructor.
  *
- * In all cases, ownership of the object is transfered to the OSSL_STORE_INFO
+ * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO
  * and will therefore be freed when the OSSL_STORE_INFO is freed.
  */
 OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name);
index 33d0ab7..190eab0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_OSSL_STOREERR_H
 # define HEADER_OSSL_STOREERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index e13b5dd..76d9fda 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  * Copyright 2005 Nokia. All rights reserved.
  *
@@ -1222,7 +1222,7 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
 /*
  * extended master secret
  */
-#  define TLS_MD_EXTENDED_MASTER_SECRET_CONST    "\x65\x78\x74\x65\x63\x64\x65\x64\x20\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
+#  define TLS_MD_EXTENDED_MASTER_SECRET_CONST    "\x65\x78\x74\x65\x6e\x64\x65\x64\x20\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
 # endif
 
 /* TLS Session Ticket extension struct */
index 3e04925..07f2333 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_TSERR_H
 # define HEADER_TSERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # include <openssl/opensslconf.h>
 
 # ifndef OPENSSL_NO_TS
index 72fd9a9..bd68864 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_UIERR_H
 # define HEADER_UIERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index b1d6a87..0273853 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_X509ERR_H
 # define HEADER_X509ERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
@@ -93,6 +97,7 @@ int ERR_load_X509_strings(void);
 # define X509_R_CRL_ALREADY_DELTA                         127
 # define X509_R_CRL_VERIFY_FAILURE                        131
 # define X509_R_IDP_MISMATCH                              128
+# define X509_R_INVALID_ATTRIBUTES                        138
 # define X509_R_INVALID_DIRECTORY                         113
 # define X509_R_INVALID_FIELD_NAME                        119
 # define X509_R_INVALID_TRUST                             123
index 9ea2027..6c6eca3 100644 (file)
@@ -661,6 +661,8 @@ uint32_t X509_get_key_usage(X509 *x);
 uint32_t X509_get_extended_key_usage(X509 *x);
 const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x);
 const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x);
+const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x);
+const ASN1_INTEGER *X509_get0_authority_serial(X509 *x);
 
 int X509_PURPOSE_get_count(void);
 X509_PURPOSE *X509_PURPOSE_get0(int idx);
index 6b3df12..5f25442 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #ifndef HEADER_X509V3ERR_H
 # define HEADER_X509V3ERR_H
 
+# ifndef HEADER_SYMHACKS_H
+#  include <openssl/symhacks.h>
+# endif
+
 # ifdef  __cplusplus
 extern "C"
 # endif
index 5906e88..6365b36 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -52,8 +52,7 @@ int dtls1_dispatch_alert(SSL *s)
         s->s3->alert_dispatch = 1;
         /* fprintf( stderr, "not done with alert\n" ); */
     } else {
-        if (s->s3->send_alert[0] == SSL3_AL_FATAL)
-            (void)BIO_flush(s->wbio);
+        (void)BIO_flush(s->wbio);
 
         if (s->msg_callback)
             s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert,
index b2f97ef..982a060 100644 (file)
@@ -374,6 +374,13 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len,
     s->rlayer.wnum = 0;
 
     /*
+     * If we are supposed to be sending a KeyUpdate then go into init unless we
+     * have writes pending - in which case we should finish doing that first.
+     */
+    if (wb->left == 0 && s->key_update != SSL_KEY_UPDATE_NONE)
+        ossl_statem_set_in_init(s, 1);
+
+    /*
      * When writing early data on the server side we could be "in_init" in
      * between receiving the EoED and the CF - but we don't want to handle those
      * messages yet.
@@ -628,8 +635,9 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len,
              */
             s->s3->empty_fragment_done = 0;
 
-            if ((i == (int)n) && s->mode & SSL_MODE_RELEASE_BUFFERS &&
-                !SSL_IS_DTLS(s))
+            if (tmpwrit == n
+                    && (s->mode & SSL_MODE_RELEASE_BUFFERS) != 0
+                    && !SSL_IS_DTLS(s))
                 ssl3_release_write_buffer(s);
 
             *written = tot + tmpwrit;
index 99ae481..066bf47 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  * Copyright 2005 Nokia. All rights reserved.
  *
@@ -3567,6 +3567,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 
     case SSL_CTRL_GET_CHAIN_CERTS:
         *(STACK_OF(X509) **)parg = s->cert->key->chain;
+        ret = 1;
         break;
 
     case SSL_CTRL_SELECT_CURRENT_CERT:
@@ -3601,8 +3602,8 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 
             if (!s->session)
                 return 0;
-            clist = s->session->ext.supportedgroups;
-            clistlen = s->session->ext.supportedgroups_len;
+            clist = s->ext.peer_supportedgroups;
+            clistlen = s->ext.peer_supportedgroups_len;
             if (parg) {
                 size_t i;
                 int *cptr = parg;
@@ -3716,13 +3717,12 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 #ifndef OPENSSL_NO_EC
     case SSL_CTRL_GET_EC_POINT_FORMATS:
         {
-            SSL_SESSION *sess = s->session;
             const unsigned char **pformat = parg;
 
-            if (sess == NULL || sess->ext.ecpointformats == NULL)
+            if (s->ext.peer_ecpointformats == NULL)
                 return 0;
-            *pformat = sess->ext.ecpointformats;
-            return (int)sess->ext.ecpointformats_len;
+            *pformat = s->ext.peer_ecpointformats;
+            return (int)s->ext.peer_ecpointformats_len;
         }
 #endif
 
index 3314507..9df9fb9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
@@ -154,8 +154,6 @@ CERT *ssl_cert_dup(CERT *cert)
         ret->client_sigalgslen = cert->client_sigalgslen;
     } else
         ret->client_sigalgs = NULL;
-    /* Shared sigalgs also NULL */
-    ret->shared_sigalgs = NULL;
     /* Copy any custom client certificate types */
     if (cert->ctype) {
         ret->ctype = OPENSSL_memdup(cert->ctype, cert->ctype_len);
@@ -240,7 +238,6 @@ void ssl_cert_free(CERT *c)
     ssl_cert_clear_certs(c);
     OPENSSL_free(c->conf_sigalgs);
     OPENSSL_free(c->client_sigalgs);
-    OPENSSL_free(c->shared_sigalgs);
     OPENSSL_free(c->ctype);
     X509_STORE_free(c->verify_store);
     X509_STORE_free(c->chain_store);
index b60d67a..27a1b2e 100644 (file)
@@ -1377,24 +1377,25 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str)
 {
     int ret = set_ciphersuites(&(ctx->tls13_ciphersuites), str);
 
-    if (ret && ctx->cipher_list != NULL) {
-        /* We already have a cipher_list, so we need to update it */
+    if (ret && ctx->cipher_list != NULL)
         return update_cipher_list(&ctx->cipher_list, &ctx->cipher_list_by_id,
                                   ctx->tls13_ciphersuites);
-    }
 
     return ret;
 }
 
 int SSL_set_ciphersuites(SSL *s, const char *str)
 {
+    STACK_OF(SSL_CIPHER) *cipher_list;
     int ret = set_ciphersuites(&(s->tls13_ciphersuites), str);
 
-    if (ret && s->cipher_list != NULL) {
-        /* We already have a cipher_list, so we need to update it */
+    if (s->cipher_list == NULL) {
+        if ((cipher_list = SSL_get_ciphers(s)) != NULL)
+            s->cipher_list = sk_SSL_CIPHER_dup(cipher_list);
+    }
+    if (ret && s->cipher_list != NULL)
         return update_cipher_list(&s->cipher_list, &s->cipher_list_by_id,
                                   s->tls13_ciphersuites);
-    }
 
     return ret;
 }
index f559bc1..ac820cf 100644 (file)
@@ -628,6 +628,11 @@ int SSL_clear(SSL *s)
     /* Clear the verification result peername */
     X509_VERIFY_PARAM_move_peername(s->param, NULL);
 
+    /* Clear any shared connection state */
+    OPENSSL_free(s->shared_sigalgs);
+    s->shared_sigalgs = NULL;
+    s->shared_sigalgslen = 0;
+
     /*
      * Check to see if we were changed into a different method, if so, revert
      * back.
@@ -867,7 +872,7 @@ int SSL_up_ref(SSL *s)
 int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
                                    unsigned int sid_ctx_len)
 {
-    if (sid_ctx_len > sizeof(ctx->sid_ctx)) {
+    if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
         SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT,
                SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
         return 0;
@@ -1160,6 +1165,7 @@ void SSL_free(SSL *s)
     sk_SSL_CIPHER_free(s->cipher_list);
     sk_SSL_CIPHER_free(s->cipher_list_by_id);
     sk_SSL_CIPHER_free(s->tls13_ciphersuites);
+    sk_SSL_CIPHER_free(s->peer_ciphers);
 
     /* Make the next call work :-) */
     if (s->session != NULL) {
@@ -1172,13 +1178,16 @@ void SSL_free(SSL *s)
     clear_ciphers(s);
 
     ssl_cert_free(s->cert);
+    OPENSSL_free(s->shared_sigalgs);
     /* Free up if allocated */
 
     OPENSSL_free(s->ext.hostname);
     SSL_CTX_free(s->session_ctx);
 #ifndef OPENSSL_NO_EC
     OPENSSL_free(s->ext.ecpointformats);
+    OPENSSL_free(s->ext.peer_ecpointformats);
     OPENSSL_free(s->ext.supportedgroups);
+    OPENSSL_free(s->ext.peer_supportedgroups);
 #endif                          /* OPENSSL_NO_EC */
     sk_X509_EXTENSION_pop_free(s->ext.ocsp.exts, X509_EXTENSION_free);
 #ifndef OPENSSL_NO_OCSP
@@ -2437,9 +2446,9 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s)
 
 STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s)
 {
-    if ((s == NULL) || (s->session == NULL) || !s->server)
+    if ((s == NULL) || !s->server)
         return NULL;
-    return s->session->ciphers;
+    return s->peer_ciphers;
 }
 
 STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s)
@@ -2578,13 +2587,12 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size)
     int i;
 
     if (!s->server
-            || s->session == NULL
-            || s->session->ciphers == NULL
+            || s->peer_ciphers == NULL
             || size < 2)
         return NULL;
 
     p = buf;
-    clntsk = s->session->ciphers;
+    clntsk = s->peer_ciphers;
     srvrsk = SSL_get_ciphers(s);
     if (clntsk == NULL || srvrsk == NULL)
         return NULL;
index 0cf3893..25875c9 100644 (file)
@@ -552,7 +552,6 @@ struct ssl_session_st {
     const SSL_CIPHER *cipher;
     unsigned long cipher_id;    /* when ASN.1 loaded, this needs to be used to
                                  * load the 'cipher' structure */
-    STACK_OF(SSL_CIPHER) *ciphers; /* ciphers offered by the client */
     CRYPTO_EX_DATA ex_data;     /* application specific data */
     /*
      * These are used to make removal of session-ids more efficient and to
@@ -562,13 +561,7 @@ struct ssl_session_st {
 
     struct {
         char *hostname;
-# ifndef OPENSSL_NO_EC
-        size_t ecpointformats_len;
-        unsigned char *ecpointformats; /* peer's list */
-# endif                         /* OPENSSL_NO_EC */
-        size_t supportedgroups_len;
-        uint16_t *supportedgroups; /* peer's list */
-    /* RFC4507 info */
+        /* RFC4507 info */
         unsigned char *tick; /* Session ticket */
         size_t ticklen;      /* Session ticket length */
         /* Session lifetime hint in seconds */
@@ -1137,6 +1130,7 @@ struct ssl_st {
     /* Per connection DANE state */
     SSL_DANE dane;
     /* crypto */
+    STACK_OF(SSL_CIPHER) *peer_ciphers;
     STACK_OF(SSL_CIPHER) *cipher_list;
     STACK_OF(SSL_CIPHER) *cipher_list_by_id;
     /* TLSv1.3 specific ciphersuites */
@@ -1300,10 +1294,19 @@ struct ssl_st {
         size_t ecpointformats_len;
         /* our list */
         unsigned char *ecpointformats;
+
+        size_t peer_ecpointformats_len;
+        /* peer's list */
+        unsigned char *peer_ecpointformats;
 # endif                         /* OPENSSL_NO_EC */
         size_t supportedgroups_len;
         /* our list */
         uint16_t *supportedgroups;
+
+        size_t peer_supportedgroups_len;
+         /* peer's list */
+        uint16_t *peer_supportedgroups;
+
         /* TLS Session Ticket extension override */
         TLS_SESSION_TICKET_EXT *session_ticket;
         /* TLS Session Ticket extension callback */
@@ -1459,7 +1462,6 @@ struct ssl_st {
     size_t block_padding;
 
     CRYPTO_RWLOCK *lock;
-    RAND_DRBG *drbg;
 
     /* The number of TLS1.3 tickets to automatically send */
     size_t num_tickets;
@@ -1471,6 +1473,13 @@ struct ssl_st {
     /* Callback to determine if early_data is acceptable or not */
     SSL_allow_early_data_cb_fn allow_early_data_cb;
     void *allow_early_data_cb_data;
+
+    /*
+     * Signature algorithms shared by client and server: cached because these
+     * are used most often.
+     */
+    const struct sigalg_lookup_st **shared_sigalgs;
+    size_t shared_sigalgslen;
 };
 
 /*
@@ -1905,12 +1914,6 @@ typedef struct cert_st {
     /* Size of above array */
     size_t client_sigalgslen;
     /*
-     * Signature algorithms shared by client and server: cached because these
-     * are used most often.
-     */
-    const SIGALG_LOOKUP **shared_sigalgs;
-    size_t shared_sigalgslen;
-    /*
      * Certificate setup callback: if set is called whenever a certificate
      * may be required (client or server). the callback can then examine any
      * appropriate parameters and setup any certificates required. This
@@ -2240,8 +2243,8 @@ static ossl_inline int ssl_has_cert(const SSL *s, int idx)
 static ossl_inline void tls1_get_peer_groups(SSL *s, const uint16_t **pgroups,
                                              size_t *pgroupslen)
 {
-    *pgroups = s->session->ext.supportedgroups;
-    *pgroupslen = s->session->ext.supportedgroups_len;
+    *pgroups = s->ext.peer_supportedgroups;
+    *pgroupslen = s->ext.peer_supportedgroups_len;
 }
 
 # ifndef OPENSSL_UNIT_TEST
index 5ad2792..52cfa7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright 2005 Nokia. All rights reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
@@ -121,12 +121,7 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
     dest->psk_identity_hint = NULL;
     dest->psk_identity = NULL;
 #endif
-    dest->ciphers = NULL;
     dest->ext.hostname = NULL;
-#ifndef OPENSSL_NO_EC
-    dest->ext.ecpointformats = NULL;
-    dest->ext.supportedgroups = NULL;
-#endif
     dest->ext.tick = NULL;
     dest->ext.alpn_selected = NULL;
 #ifndef OPENSSL_NO_SRP
@@ -176,12 +171,6 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
     }
 #endif
 
-    if (src->ciphers != NULL) {
-        dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
-        if (dest->ciphers == NULL)
-            goto err;
-    }
-
     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
                             &dest->ex_data, &src->ex_data)) {
         goto err;
@@ -193,23 +182,6 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
             goto err;
         }
     }
-#ifndef OPENSSL_NO_EC
-    if (src->ext.ecpointformats) {
-        dest->ext.ecpointformats =
-            OPENSSL_memdup(src->ext.ecpointformats,
-                           src->ext.ecpointformats_len);
-        if (dest->ext.ecpointformats == NULL)
-            goto err;
-    }
-    if (src->ext.supportedgroups) {
-        dest->ext.supportedgroups =
-            OPENSSL_memdup(src->ext.supportedgroups,
-                           src->ext.supportedgroups_len
-                                * sizeof(*src->ext.supportedgroups));
-        if (dest->ext.supportedgroups == NULL)
-            goto err;
-    }
-#endif
 
     if (ticket != 0 && src->ext.tick != NULL) {
         dest->ext.tick =
@@ -790,17 +762,8 @@ void SSL_SESSION_free(SSL_SESSION *ss)
     OPENSSL_cleanse(ss->session_id, sizeof(ss->session_id));
     X509_free(ss->peer);
     sk_X509_pop_free(ss->peer_chain, X509_free);
-    sk_SSL_CIPHER_free(ss->ciphers);
     OPENSSL_free(ss->ext.hostname);
     OPENSSL_free(ss->ext.tick);
-#ifndef OPENSSL_NO_EC
-    OPENSSL_free(ss->ext.ecpointformats);
-    ss->ext.ecpointformats = NULL;
-    ss->ext.ecpointformats_len = 0;
-    OPENSSL_free(ss->ext.supportedgroups);
-    ss->ext.supportedgroups = NULL;
-    ss->ext.supportedgroups_len = 0;
-#endif                          /* OPENSSL_NO_EC */
 #ifndef OPENSSL_NO_PSK
     OPENSSL_free(ss->psk_identity_hint);
     OPENSSL_free(ss->psk_identity);
index b27608c..2441099 100644 (file)
@@ -1040,18 +1040,18 @@ static int final_ec_pt_formats(SSL *s, unsigned int context, int sent)
      */
     if (s->ext.ecpointformats != NULL
             && s->ext.ecpointformats_len > 0
-            && s->session->ext.ecpointformats != NULL
-            && s->session->ext.ecpointformats_len > 0
+            && s->ext.peer_ecpointformats != NULL
+            && s->ext.peer_ecpointformats_len > 0
             && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))) {
         /* we are using an ECC cipher */
         size_t i;
-        unsigned char *list = s->session->ext.ecpointformats;
+        unsigned char *list = s->ext.peer_ecpointformats;
 
-        for (i = 0; i < s->session->ext.ecpointformats_len; i++) {
+        for (i = 0; i < s->ext.peer_ecpointformats_len; i++) {
             if (*list++ == TLSEXT_ECPOINTFORMAT_uncompressed)
                 break;
         }
-        if (i == s->session->ext.ecpointformats_len) {
+        if (i == s->ext.peer_ecpointformats_len) {
             SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_FINAL_EC_PT_FORMATS,
                      SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
             return 0;
@@ -1448,8 +1448,13 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
     unsigned char hash[EVP_MAX_MD_SIZE], binderkey[EVP_MAX_MD_SIZE];
     unsigned char finishedkey[EVP_MAX_MD_SIZE], tmpbinder[EVP_MAX_MD_SIZE];
     unsigned char *early_secret;
+#ifdef CHARSET_EBCDIC
+    static const unsigned char resumption_label[] = { 0x72, 0x65, 0x64, 0x20, 0x62, 0x69, 0x6E, 0x64, 0x65, 0x72, 0x00 };
+    static const unsigned char external_label[]   = { 0x65, 0x78, 0x74, 0x20, 0x62, 0x69, 0x6E, 0x64, 0x65, 0x72, 0x00 };
+#else
     static const unsigned char resumption_label[] = "res binder";
     static const unsigned char external_label[] = "ext binder";
+#endif
     const unsigned char *label;
     size_t bindersize, labelsize, hashsize;
     int hashsizei = EVP_MD_size(md);
@@ -1648,9 +1653,9 @@ static int final_early_data(SSL *s, unsigned int context, int sent)
             || s->early_data_state != SSL_EARLY_DATA_ACCEPTING
             || !s->ext.early_data_ok
             || s->hello_retry_request != SSL_HRR_NONE
-            || (s->ctx->allow_early_data_cb != NULL
-                && !s->ctx->allow_early_data_cb(s,
-                                         s->ctx->allow_early_data_cb_data))) {
+            || (s->allow_early_data_cb != NULL
+                && !s->allow_early_data_cb(s,
+                                         s->allow_early_data_cb_data))) {
         s->ext.early_data = SSL_EARLY_DATA_REJECTED;
     } else {
         s->ext.early_data = SSL_EARLY_DATA_ACCEPTED;
index 3c7d844..f0ae642 100644 (file)
@@ -1371,19 +1371,19 @@ int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context,
             return 0;
         }
 
-        s->session->ext.ecpointformats_len = 0;
-        OPENSSL_free(s->session->ext.ecpointformats);
-        s->session->ext.ecpointformats = OPENSSL_malloc(ecpointformats_len);
-        if (s->session->ext.ecpointformats == NULL) {
+        s->ext.peer_ecpointformats_len = 0;
+        OPENSSL_free(s->ext.peer_ecpointformats);
+        s->ext.peer_ecpointformats = OPENSSL_malloc(ecpointformats_len);
+        if (s->ext.peer_ecpointformats == NULL) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                      SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR);
             return 0;
         }
 
-        s->session->ext.ecpointformats_len = ecpointformats_len;
+        s->ext.peer_ecpointformats_len = ecpointformats_len;
 
         if (!PACKET_copy_bytes(&ecptformatlist,
-                               s->session->ext.ecpointformats,
+                               s->ext.peer_ecpointformats,
                                ecpointformats_len)) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                      SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR);
@@ -1858,8 +1858,8 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
         return 0;
     }
 
-    skey = ssl_generate_pkey(ckey);
-    if (skey == NULL) {
+    skey = EVP_PKEY_new();
+    if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
                  ERR_R_MALLOC_FAILURE);
         return 0;
index 6301b4e..ab5453f 100644 (file)
@@ -254,8 +254,8 @@ int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context,
 
     if (!s->hit) {
         if (!PACKET_memdup(&ec_point_format_list,
-                           &s->session->ext.ecpointformats,
-                           &s->session->ext.ecpointformats_len)) {
+                           &s->ext.peer_ecpointformats,
+                           &s->ext.peer_ecpointformats_len)) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                      SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR);
             return 0;
@@ -962,12 +962,12 @@ int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context,
     }
 
     if (!s->hit || SSL_IS_TLS13(s)) {
-        OPENSSL_free(s->session->ext.supportedgroups);
-        s->session->ext.supportedgroups = NULL;
-        s->session->ext.supportedgroups_len = 0;
+        OPENSSL_free(s->ext.peer_supportedgroups);
+        s->ext.peer_supportedgroups = NULL;
+        s->ext.peer_supportedgroups_len = 0;
         if (!tls1_save_u16(&supported_groups_list,
-                           &s->session->ext.supportedgroups,
-                           &s->session->ext.supportedgroups_len)) {
+                           &s->ext.peer_supportedgroups,
+                           &s->ext.peer_supportedgroups_len)) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                      SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS,
                      ERR_R_INTERNAL_ERROR);
@@ -1376,7 +1376,7 @@ EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt,
     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
     unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
     int using_ecc = ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))
-                    && (s->session->ext.ecpointformats != NULL);
+                    && (s->ext.peer_ecpointformats != NULL);
     const unsigned char *plist;
     size_t plistlen;
 
@@ -1487,6 +1487,10 @@ EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt,
                                              unsigned int context, X509 *x,
                                              size_t chainidx)
 {
+    /* We don't currently support this extension inside a CertificateRequest */
+    if (context == SSL_EXT_TLS1_3_CERTIFICATE_REQUEST)
+        return EXT_RETURN_NOT_SENT;
+
     if (!s->ext.status_expected)
         return EXT_RETURN_NOT_SENT;
 
index 87800cd..6410414 100644 (file)
@@ -473,12 +473,6 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
         return WRITE_TRAN_CONTINUE;
 
     case TLS_ST_CR_KEY_UPDATE:
-        if (s->key_update != SSL_KEY_UPDATE_NONE) {
-            st->hand_state = TLS_ST_CW_KEY_UPDATE;
-            return WRITE_TRAN_CONTINUE;
-        }
-        /* Fall through */
-
     case TLS_ST_CW_KEY_UPDATE:
     case TLS_ST_CR_SESSION_TICKET:
     case TLS_ST_CW_FINISHED:
index c0482b0..22e9f04 100644 (file)
@@ -168,9 +168,19 @@ int tls_setup_handshake(SSL *s)
 static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs,
                                     void **hdata, size_t *hdatalen)
 {
+#ifdef CHARSET_EBCDIC
+    static const char *servercontext = { 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e,
+     0x33, 0x2c, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65,
+     0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72,
+     0x69, 0x66, 0x79, 0x00 };
+    static const char *clientcontext = { 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e,
+     0x33, 0x2c, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x65,
+     0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72,
+     0x69, 0x66, 0x79, 0x00 };
+#else
     static const char *servercontext = "TLS 1.3, server CertificateVerify";
     static const char *clientcontext = "TLS 1.3, client CertificateVerify";
-
+#endif
     if (SSL_IS_TLS13(s)) {
         size_t hashlen;
 
@@ -645,12 +655,9 @@ MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt)
     /*
      * If we get a request for us to update our sending keys too then, we need
      * to additionally send a KeyUpdate message. However that message should
-     * not also request an update (otherwise we get into an infinite loop). We
-     * ignore a request for us to update our sending keys too if we already
-     * sent close_notify.
+     * not also request an update (otherwise we get into an infinite loop).
      */
-    if (updatetype == SSL_KEY_UPDATE_REQUESTED
-            && (s->shutdown & SSL_SENT_SHUTDOWN) == 0)
+    if (updatetype == SSL_KEY_UPDATE_REQUESTED)
         s->key_update = SSL_KEY_UPDATE_NOT_REQUESTED;
 
     if (!tls13_update_key(s, 0)) {
index d454326..8cf9c40 100644 (file)
@@ -502,12 +502,6 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
         return WRITE_TRAN_CONTINUE;
 
     case TLS_ST_SR_KEY_UPDATE:
-        if (s->key_update != SSL_KEY_UPDATE_NONE) {
-            st->hand_state = TLS_ST_SW_KEY_UPDATE;
-            return WRITE_TRAN_CONTINUE;
-        }
-        /* Fall through */
-
     case TLS_ST_SW_KEY_UPDATE:
         st->hand_state = TLS_ST_OK;
         return WRITE_TRAN_CONTINUE;
@@ -1927,14 +1921,14 @@ static int tls_early_post_process_client_hello(SSL *s)
                 && master_key_length > 0) {
             s->session->master_key_length = master_key_length;
             s->hit = 1;
-            s->session->ciphers = ciphers;
+            s->peer_ciphers = ciphers;
             s->session->verify_result = X509_V_OK;
 
             ciphers = NULL;
 
             /* check if some cipher was preferred by call back */
             if (pref_cipher == NULL)
-                pref_cipher = ssl3_choose_cipher(s, s->session->ciphers,
+                pref_cipher = ssl3_choose_cipher(s, s->peer_ciphers,
                                                  SSL_get_ciphers(s));
             if (pref_cipher == NULL) {
                 SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
@@ -1945,9 +1939,9 @@ static int tls_early_post_process_client_hello(SSL *s)
 
             s->session->cipher = pref_cipher;
             sk_SSL_CIPHER_free(s->cipher_list);
-            s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
+            s->cipher_list = sk_SSL_CIPHER_dup(s->peer_ciphers);
             sk_SSL_CIPHER_free(s->cipher_list_by_id);
-            s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
+            s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->peer_ciphers);
         }
     }
 
@@ -2047,12 +2041,12 @@ static int tls_early_post_process_client_hello(SSL *s)
 #endif
 
     /*
-     * Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher
+     * Given s->peer_ciphers and SSL_get_ciphers, we must pick a cipher
      */
 
     if (!s->hit || SSL_IS_TLS13(s)) {
-        sk_SSL_CIPHER_free(s->session->ciphers);
-        s->session->ciphers = ciphers;
+        sk_SSL_CIPHER_free(s->peer_ciphers);
+        s->peer_ciphers = ciphers;
         if (ciphers == NULL) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                      SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
@@ -2068,6 +2062,10 @@ static int tls_early_post_process_client_hello(SSL *s)
 #else
         s->session->compress_meth = (comp == NULL) ? 0 : comp->id;
 #endif
+        if (!tls1_set_server_sigalgs(s)) {
+            /* SSLfatal() already called */
+            goto err;
+        }
     }
 
     sk_SSL_CIPHER_free(ciphers);
@@ -2235,31 +2233,25 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst)
     if (wst == WORK_MORE_B) {
         if (!s->hit || SSL_IS_TLS13(s)) {
             /* Let cert callback update server certificates if required */
-            if (!s->hit) {
-                if (s->cert->cert_cb != NULL) {
-                    int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
-                    if (rv == 0) {
-                        SSLfatal(s, SSL_AD_INTERNAL_ERROR,
-                                 SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
-                                 SSL_R_CERT_CB_ERROR);
-                        goto err;
-                    }
-                    if (rv < 0) {
-                        s->rwstate = SSL_X509_LOOKUP;
-                        return WORK_MORE_B;
-                    }
-                    s->rwstate = SSL_NOTHING;
-                }
-                if (!tls1_set_server_sigalgs(s)) {
-                    /* SSLfatal already called */
+            if (!s->hit && s->cert->cert_cb != NULL) {
+                int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
+                if (rv == 0) {
+                    SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+                             SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
+                             SSL_R_CERT_CB_ERROR);
                     goto err;
                 }
+                if (rv < 0) {
+                    s->rwstate = SSL_X509_LOOKUP;
+                    return WORK_MORE_B;
+                }
+                s->rwstate = SSL_NOTHING;
             }
 
             /* In TLSv1.3 we selected the ciphersuite before resumption */
             if (!SSL_IS_TLS13(s)) {
                 cipher =
-                    ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
+                    ssl3_choose_cipher(s, s->peer_ciphers, SSL_get_ciphers(s));
 
                 if (cipher == NULL) {
                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
index 68cb237..b482019 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -21,6 +21,8 @@
 #include "ssl_locl.h"
 #include <openssl/ct.h>
 
+static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey);
+
 SSL3_ENC_METHOD const TLSv1_enc_data = {
     tls1_enc,
     tls1_mac,
@@ -465,11 +467,11 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey)
      * If point formats extension present check it, otherwise everything is
      * supported (see RFC4492).
      */
-    if (s->session->ext.ecpointformats == NULL)
+    if (s->ext.peer_ecpointformats == NULL)
         return 1;
 
-    for (i = 0; i < s->session->ext.ecpointformats_len; i++) {
-        if (s->session->ext.ecpointformats[i] == comp_id)
+    for (i = 0; i < s->ext.peer_ecpointformats_len; i++) {
+        if (s->ext.peer_ecpointformats[i] == comp_id)
             return 1;
     }
     return 0;
@@ -578,7 +580,6 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md)
     if (check_ee_md && tls1_suiteb(s)) {
         int check_md;
         size_t i;
-        CERT *c = s->cert;
 
         /* Check to see we have necessary signing algorithm */
         if (group_id == TLSEXT_curve_P_256)
@@ -587,8 +588,8 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md)
             check_md = NID_ecdsa_with_SHA384;
         else
             return 0;           /* Should never happen */
-        for (i = 0; i < c->shared_sigalgslen; i++) {
-            if (check_md == c->shared_sigalgs[i]->sigandhash)
+        for (i = 0; i < s->shared_sigalgslen; i++) {
+            if (check_md == s->shared_sigalgs[i]->sigandhash)
                 return 1;;
         }
         return 0;
@@ -1215,9 +1216,9 @@ int tls1_set_server_sigalgs(SSL *s)
     size_t i;
 
     /* Clear any shared signature algorithms */
-    OPENSSL_free(s->cert->shared_sigalgs);
-    s->cert->shared_sigalgs = NULL;
-    s->cert->shared_sigalgslen = 0;
+    OPENSSL_free(s->shared_sigalgs);
+    s->shared_sigalgs = NULL;
+    s->shared_sigalgslen = 0;
     /* Clear certificate validity flags */
     for (i = 0; i < SSL_PKEY_NUM; i++)
         s->s3->tmp.valid_flags[i] = 0;
@@ -1252,7 +1253,7 @@ int tls1_set_server_sigalgs(SSL *s)
                  SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_INTERNAL_ERROR);
         return 0;
     }
-    if (s->cert->shared_sigalgs != NULL)
+    if (s->shared_sigalgs != NULL)
         return 1;
 
     /* Fatal error if no shared signature algorithms */
@@ -1724,9 +1725,9 @@ static int tls1_set_shared_sigalgs(SSL *s)
     CERT *c = s->cert;
     unsigned int is_suiteb = tls1_suiteb(s);
 
-    OPENSSL_free(c->shared_sigalgs);
-    c->shared_sigalgs = NULL;
-    c->shared_sigalgslen = 0;
+    OPENSSL_free(s->shared_sigalgs);
+    s->shared_sigalgs = NULL;
+    s->shared_sigalgslen = 0;
     /* If client use client signature algorithms if not NULL */
     if (!s->server && c->client_sigalgs && !is_suiteb) {
         conf = c->client_sigalgs;
@@ -1757,8 +1758,8 @@ static int tls1_set_shared_sigalgs(SSL *s)
     } else {
         salgs = NULL;
     }
-    c->shared_sigalgs = salgs;
-    c->shared_sigalgslen = nmatch;
+    s->shared_sigalgs = salgs;
+    s->shared_sigalgslen = nmatch;
     return 1;
 }
 
@@ -1819,7 +1820,6 @@ int tls1_process_sigalgs(SSL *s)
 {
     size_t i;
     uint32_t *pvalid = s->s3->tmp.valid_flags;
-    CERT *c = s->cert;
 
     if (!tls1_set_shared_sigalgs(s))
         return 0;
@@ -1827,8 +1827,8 @@ int tls1_process_sigalgs(SSL *s)
     for (i = 0; i < SSL_PKEY_NUM; i++)
         pvalid[i] = 0;
 
-    for (i = 0; i < c->shared_sigalgslen; i++) {
-        const SIGALG_LOOKUP *sigptr = c->shared_sigalgs[i];
+    for (i = 0; i < s->shared_sigalgslen; i++) {
+        const SIGALG_LOOKUP *sigptr = s->shared_sigalgs[i];
         int idx = sigptr->sig_idx;
 
         /* Ignore PKCS1 based sig algs in TLSv1.3 */
@@ -1875,12 +1875,12 @@ int SSL_get_shared_sigalgs(SSL *s, int idx,
                            unsigned char *rsig, unsigned char *rhash)
 {
     const SIGALG_LOOKUP *shsigalgs;
-    if (s->cert->shared_sigalgs == NULL
+    if (s->shared_sigalgs == NULL
         || idx < 0
-        || idx >= (int)s->cert->shared_sigalgslen
-        || s->cert->shared_sigalgslen > INT_MAX)
+        || idx >= (int)s->shared_sigalgslen
+        || s->shared_sigalgslen > INT_MAX)
         return 0;
-    shsigalgs = s->cert->shared_sigalgs[idx];
+    shsigalgs = s->shared_sigalgs[idx];
     if (phash != NULL)
         *phash = shsigalgs->hash;
     if (psign != NULL)
@@ -1891,7 +1891,7 @@ int SSL_get_shared_sigalgs(SSL *s, int idx,
         *rsig = (unsigned char)(shsigalgs->sigalg & 0xff);
     if (rhash != NULL)
         *rhash = (unsigned char)((shsigalgs->sigalg >> 8) & 0xff);
-    return (int)s->cert->shared_sigalgslen;
+    return (int)s->shared_sigalgslen;
 }
 
 /* Maximum possible number of unique entries in sigalgs array */
@@ -2072,18 +2072,36 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
     return 0;
 }
 
-static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid)
+static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid)
 {
-    int sig_nid;
+    int sig_nid, use_pc_sigalgs = 0;
     size_t i;
+    const SIGALG_LOOKUP *sigalg;
+    size_t sigalgslen;
     if (default_nid == -1)
         return 1;
     sig_nid = X509_get_signature_nid(x);
     if (default_nid)
         return sig_nid == default_nid ? 1 : 0;
-    for (i = 0; i < c->shared_sigalgslen; i++)
-        if (sig_nid == c->shared_sigalgs[i]->sigandhash)
+
+    if (SSL_IS_TLS13(s) && s->s3->tmp.peer_cert_sigalgs != NULL) {
+        /*
+         * If we're in TLSv1.3 then we only get here if we're checking the
+         * chain. If the peer has specified peer_cert_sigalgs then we use them
+         * otherwise we default to normal sigalgs.
+         */
+        sigalgslen = s->s3->tmp.peer_cert_sigalgslen;
+        use_pc_sigalgs = 1;
+    } else {
+        sigalgslen = s->shared_sigalgslen;
+    }
+    for (i = 0; i < sigalgslen; i++) {
+        sigalg = use_pc_sigalgs
+                 ? tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i])
+                 : s->shared_sigalgs[i];
+        if (sig_nid == sigalg->sigandhash)
             return 1;
+    }
     return 0;
 }
 
@@ -2240,14 +2258,21 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
             }
         }
         /* Check signature algorithm of each cert in chain */
-        if (!tls1_check_sig_alg(c, x, default_nid)) {
+        if (SSL_IS_TLS13(s)) {
+            /*
+             * We only get here if the application has called SSL_check_chain(),
+             * so check_flags is always set.
+             */
+            if (find_sig_alg(s, x, pk) != NULL)
+                rv |= CERT_PKEY_EE_SIGNATURE;
+        } else if (!tls1_check_sig_alg(s, x, default_nid)) {
             if (!check_flags)
                 goto end;
         } else
             rv |= CERT_PKEY_EE_SIGNATURE;
         rv |= CERT_PKEY_CA_SIGNATURE;
         for (i = 0; i < sk_X509_num(chain); i++) {
-            if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) {
+            if (!tls1_check_sig_alg(s, sk_X509_value(chain, i), default_nid)) {
                 if (check_flags) {
                     rv &= ~CERT_PKEY_CA_SIGNATURE;
                     break;
@@ -2528,44 +2553,33 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu)
 }
 
 /*
- * Returns true if |s| has a usable certificate configured for use
- * with signature scheme |sig|.
- * "Usable" includes a check for presence as well as applying
- * the signature_algorithm_cert restrictions sent by the peer (if any).
- * Returns false if no usable certificate is found.
+ * Checks the given cert against signature_algorithm_cert restrictions sent by
+ * the peer (if any) as well as whether the hash from the sigalg is usable with
+ * the key.
+ * Returns true if the cert is usable and false otherwise.
  */
-static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
+static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x,
+                             EVP_PKEY *pkey)
 {
     const SIGALG_LOOKUP *lu;
     int mdnid, pknid, default_mdnid;
-    int mandatory_md = 0;
     size_t i;
 
-    /* TLS 1.2 callers can override lu->sig_idx, but not TLS 1.3 callers. */
-    if (idx == -1)
-        idx = sig->sig_idx;
-    if (!ssl_has_cert(s, idx))
-        return 0;
     /* If the EVP_PKEY reports a mandatory digest, allow nothing else. */
     ERR_set_mark();
-    switch (EVP_PKEY_get_default_digest_nid(s->cert->pkeys[idx].privatekey,
-                                            &default_mdnid)) {
-    case 2:
-        mandatory_md = 1;
-        break;
-    case 1:
-        break;
-    default: /* If it didn't report a mandatory NID, for whatever reasons,
-              * just clear the error and allow all hashes to be used. */
-        ERR_pop_to_mark();
-    }
+    if (EVP_PKEY_get_default_digest_nid(pkey, &default_mdnid) == 2 &&
+        sig->hash != default_mdnid)
+            return 0;
+
+    /* If it didn't report a mandatory NID, for whatever reasons,
+     * just clear the error and allow all hashes to be used. */
+    ERR_pop_to_mark();
+
     if (s->s3->tmp.peer_cert_sigalgs != NULL) {
         for (i = 0; i < s->s3->tmp.peer_cert_sigalgslen; i++) {
             lu = tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i]);
             if (lu == NULL
-                || !X509_get_signature_info(s->cert->pkeys[idx].x509, &mdnid,
-                                            &pknid, NULL, NULL)
-                || (mandatory_md && mdnid != default_mdnid))
+                || !X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL))
                 continue;
             /*
              * TODO this does not differentiate between the
@@ -2578,7 +2592,104 @@ static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
         }
         return 0;
     }
-    return !mandatory_md || sig->hash == default_mdnid;
+    return 1;
+}
+
+/*
+ * Returns true if |s| has a usable certificate configured for use
+ * with signature scheme |sig|.
+ * "Usable" includes a check for presence as well as applying
+ * the signature_algorithm_cert restrictions sent by the peer (if any).
+ * Returns false if no usable certificate is found.
+ */
+static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
+{
+    /* TLS 1.2 callers can override sig->sig_idx, but not TLS 1.3 callers. */
+    if (idx == -1)
+        idx = sig->sig_idx;
+    if (!ssl_has_cert(s, idx))
+        return 0;
+
+    return check_cert_usable(s, sig, s->cert->pkeys[idx].x509,
+                             s->cert->pkeys[idx].privatekey);
+}
+
+/*
+ * Returns true if the supplied cert |x| and key |pkey| is usable with the
+ * specified signature scheme |sig|, or false otherwise.
+ */
+static int is_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x,
+                          EVP_PKEY *pkey)
+{
+    size_t idx;
+
+    if (ssl_cert_lookup_by_pkey(pkey, &idx) == NULL)
+        return 0;
+
+    /* Check the key is consistent with the sig alg */
+    if ((int)idx != sig->sig_idx)
+        return 0;
+
+    return check_cert_usable(s, sig, x, pkey);
+}
+
+/*
+ * Find a signature scheme that works with the supplied certificate |x| and key
+ * |pkey|. |x| and |pkey| may be NULL in which case we additionally look at our
+ * available certs/keys to find one that works.
+ */
+static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey)
+{
+    const SIGALG_LOOKUP *lu = NULL;
+    size_t i;
+#ifndef OPENSSL_NO_EC
+    int curve = -1;
+#endif
+    EVP_PKEY *tmppkey;
+
+    /* Look for a shared sigalgs matching possible certificates */
+    for (i = 0; i < s->shared_sigalgslen; i++) {
+        lu = s->shared_sigalgs[i];
+
+        /* Skip SHA1, SHA224, DSA and RSA if not PSS */
+        if (lu->hash == NID_sha1
+            || lu->hash == NID_sha224
+            || lu->sig == EVP_PKEY_DSA
+            || lu->sig == EVP_PKEY_RSA)
+            continue;
+        /* Check that we have a cert, and signature_algorithms_cert */
+        if (!tls1_lookup_md(lu, NULL))
+            continue;
+        if ((pkey == NULL && !has_usable_cert(s, lu, -1))
+                || (pkey != NULL && !is_cert_usable(s, lu, x, pkey)))
+            continue;
+
+        tmppkey = (pkey != NULL) ? pkey
+                                 : s->cert->pkeys[lu->sig_idx].privatekey;
+
+        if (lu->sig == EVP_PKEY_EC) {
+#ifndef OPENSSL_NO_EC
+            if (curve == -1) {
+                EC_KEY *ec = EVP_PKEY_get0_EC_KEY(tmppkey);
+                curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+            }
+            if (lu->curve != NID_undef && curve != lu->curve)
+                continue;
+#else
+            continue;
+#endif
+        } else if (lu->sig == EVP_PKEY_RSA_PSS) {
+            /* validate that key is large enough for the signature algorithm */
+            if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(tmppkey), lu))
+                continue;
+        }
+        break;
+    }
+
+    if (i == s->shared_sigalgslen)
+        return NULL;
+
+    return lu;
 }
 
 /*
@@ -2601,48 +2712,8 @@ int tls_choose_sigalg(SSL *s, int fatalerrs)
     s->s3->tmp.sigalg = NULL;
 
     if (SSL_IS_TLS13(s)) {
-        size_t i;
-#ifndef OPENSSL_NO_EC
-        int curve = -1;
-#endif
-
-        /* Look for a certificate matching shared sigalgs */
-        for (i = 0; i < s->cert->shared_sigalgslen; i++) {
-            lu = s->cert->shared_sigalgs[i];
-            sig_idx = -1;
-
-            /* Skip SHA1, SHA224, DSA and RSA if not PSS */
-            if (lu->hash == NID_sha1
-                || lu->hash == NID_sha224
-                || lu->sig == EVP_PKEY_DSA
-                || lu->sig == EVP_PKEY_RSA)
-                continue;
-            /* Check that we have a cert, and signature_algorithms_cert */
-            if (!tls1_lookup_md(lu, NULL) || !has_usable_cert(s, lu, -1))
-                continue;
-            if (lu->sig == EVP_PKEY_EC) {
-#ifndef OPENSSL_NO_EC
-                if (curve == -1) {
-                    EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey);
-
-                    curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
-                }
-                if (lu->curve != NID_undef && curve != lu->curve)
-                    continue;
-#else
-                continue;
-#endif
-            } else if (lu->sig == EVP_PKEY_RSA_PSS) {
-                /* validate that key is large enough for the signature algorithm */
-                EVP_PKEY *pkey;
-
-                pkey = s->cert->pkeys[lu->sig_idx].privatekey;
-                if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(pkey), lu))
-                    continue;
-            }
-            break;
-        }
-        if (i == s->cert->shared_sigalgslen) {
+        lu = find_sig_alg(s, NULL, NULL);
+        if (lu == NULL) {
             if (!fatalerrs)
                 return 1;
             SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CHOOSE_SIGALG,
@@ -2675,8 +2746,8 @@ int tls_choose_sigalg(SSL *s, int fatalerrs)
                  * Find highest preference signature algorithm matching
                  * cert type
                  */
-                for (i = 0; i < s->cert->shared_sigalgslen; i++) {
-                    lu = s->cert->shared_sigalgs[i];
+                for (i = 0; i < s->shared_sigalgslen; i++) {
+                    lu = s->shared_sigalgs[i];
 
                     if (s->server) {
                         if ((sig_idx = tls12_get_cert_sigalg_idx(s, lu)) == -1)
@@ -2703,7 +2774,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs)
 #endif
                         break;
                 }
-                if (i == s->cert->shared_sigalgslen) {
+                if (i == s->shared_sigalgslen) {
                     if (!fatalerrs)
                         return 1;
                     SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
index 1f956e6..b5f57a0 100644 (file)
@@ -30,7 +30,11 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
                              const unsigned char *data, size_t datalen,
                              unsigned char *out, size_t outlen, int fatal)
 {
+#ifdef CHARSET_EBCDIC
+    static const unsigned char label_prefix[] = { 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20, 0x00 };
+#else
     static const unsigned char label_prefix[] = "tls13 ";
+#endif
     EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
     int ret;
     size_t hkdflabellen;
@@ -112,7 +116,11 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
 int tls13_derive_key(SSL *s, const EVP_MD *md, const unsigned char *secret,
                      unsigned char *key, size_t keylen)
 {
-    static const unsigned char keylabel[] = "key";
+#ifdef CHARSET_EBCDIC
+  static const unsigned char keylabel[] ={ 0x6B, 0x65, 0x79, 0x00 };
+#else
+  static const unsigned char keylabel[] = "key";
+#endif
 
     return tls13_hkdf_expand(s, md, secret, keylabel, sizeof(keylabel) - 1,
                              NULL, 0, key, keylen, 1);
@@ -125,7 +133,11 @@ int tls13_derive_key(SSL *s, const EVP_MD *md, const unsigned char *secret,
 int tls13_derive_iv(SSL *s, const EVP_MD *md, const unsigned char *secret,
                     unsigned char *iv, size_t ivlen)
 {
-    static const unsigned char ivlabel[] = "iv";
+#ifdef CHARSET_EBCDIC
+  static const unsigned char ivlabel[] = { 0x69, 0x76, 0x00 };
+#else
+  static const unsigned char ivlabel[] = "iv";
+#endif
 
     return tls13_hkdf_expand(s, md, secret, ivlabel, sizeof(ivlabel) - 1,
                              NULL, 0, iv, ivlen, 1);
@@ -135,7 +147,11 @@ int tls13_derive_finishedkey(SSL *s, const EVP_MD *md,
                              const unsigned char *secret,
                              unsigned char *fin, size_t finlen)
 {
-    static const unsigned char finishedlabel[] = "finished";
+#ifdef CHARSET_EBCDIC
+  static const unsigned char finishedlabel[] = { 0x66, 0x69, 0x6E, 0x69, 0x73, 0x68, 0x65, 0x64, 0x00 };
+#else
+  static const unsigned char finishedlabel[] = "finished";
+#endif
 
     return tls13_hkdf_expand(s, md, secret, finishedlabel,
                              sizeof(finishedlabel) - 1, NULL, 0, fin, finlen, 1);
@@ -156,7 +172,11 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
     int mdleni;
     int ret;
     EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
+#ifdef CHARSET_EBCDIC
+    static const char derived_secret_label[] = { 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x64, 0x00 };
+#else
     static const char derived_secret_label[] = "derived";
+#endif
     unsigned char preextractsec[EVP_MAX_MD_SIZE];
 
     if (pctx == NULL) {
@@ -409,6 +429,16 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
 
 int tls13_change_cipher_state(SSL *s, int which)
 {
+#ifdef CHARSET_EBCDIC
+  static const unsigned char client_early_traffic[]       = {0x63, 0x20, 0x65, 0x20,       /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
+  static const unsigned char client_handshake_traffic[]   = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
+  static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
+  static const unsigned char server_handshake_traffic[]   = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
+  static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
+  static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20,                    /* master*/  0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
+  static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20,                  /* master*/  0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
+  static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20,  /* master*/  0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
+#else
     static const unsigned char client_early_traffic[] = "c e traffic";
     static const unsigned char client_handshake_traffic[] = "c hs traffic";
     static const unsigned char client_application_traffic[] = "c ap traffic";
@@ -417,6 +447,7 @@ int tls13_change_cipher_state(SSL *s, int which)
     static const unsigned char exporter_master_secret[] = "exp master";
     static const unsigned char resumption_master_secret[] = "res master";
     static const unsigned char early_exporter_master_secret[] = "e exp master";
+#endif
     unsigned char *iv;
     unsigned char secret[EVP_MAX_MD_SIZE];
     unsigned char hashval[EVP_MAX_MD_SIZE];
@@ -684,7 +715,11 @@ int tls13_change_cipher_state(SSL *s, int which)
 
 int tls13_update_key(SSL *s, int sending)
 {
-    static const unsigned char application_traffic[] = "traffic upd";
+#ifdef CHARSET_EBCDIC
+  static const unsigned char application_traffic[] = { 0x74, 0x72 ,0x61 ,0x66 ,0x66 ,0x69 ,0x63 ,0x20 ,0x75 ,0x70 ,0x64, 0x00};
+#else
+  static const unsigned char application_traffic[] = "traffic upd";
+#endif
     const EVP_MD *md = ssl_handshake_md(s);
     size_t hashlen = EVP_MD_size(md);
     unsigned char *insecret, *iv;
@@ -741,7 +776,11 @@ int tls13_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                                  size_t contextlen, int use_context)
 {
     unsigned char exportsecret[EVP_MAX_MD_SIZE];
+#ifdef CHARSET_EBCDIC
+    static const unsigned char exporterlabel[] = {0x65, 0x78, 0x70, 0x6F, 0x72, 0x74, 0x65, 0x72, 0x00};
+#else
     static const unsigned char exporterlabel[] = "exporter";
+#endif
     unsigned char hash[EVP_MAX_MD_SIZE], data[EVP_MAX_MD_SIZE];
     const EVP_MD *md = ssl_handshake_md(s);
     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
@@ -778,7 +817,11 @@ int tls13_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
                                        const unsigned char *context,
                                        size_t contextlen)
 {
-    static const unsigned char exporterlabel[] = "exporter";
+#ifdef CHARSET_EBCDIC
+  static const unsigned char exporterlabel[] = {0x65, 0x78, 0x70, 0x6F, 0x72, 0x74, 0x65, 0x72, 0x00};
+#else
+  static const unsigned char exporterlabel[] = "exporter";
+#endif
     unsigned char exportsecret[EVP_MAX_MD_SIZE];
     unsigned char hash[EVP_MAX_MD_SIZE], data[EVP_MAX_MD_SIZE];
     const EVP_MD *md;
index 1df630f..b43763d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -24,8 +24,8 @@ struct testdata {
     int expected_type;      /* expected type after set/set_string_gmt */
     int check_result;       /* check result */
     time_t t;               /* expected time_t*/
-    int cmp_result;         /* compariston to baseline result */
-    int convert_result;     /* convertion result */
+    int cmp_result;         /* comparison to baseline result */
+    int convert_result;     /* conversion result */
 };
 
 static struct testdata tbl_testdata_pos[] = {
index 9724148..383c82d 100644 (file)
@@ -181,6 +181,45 @@ finish:
     return ok;
 }
 
+static int test_bio_nonclear_rst(void)
+{
+    int ok = 0;
+    BIO *bio = NULL;
+    char data[16];
+
+    bio = BIO_new(BIO_s_mem());
+    if (!TEST_ptr(bio))
+        goto finish;
+    if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
+        goto finish;
+
+    BIO_set_flags(bio, BIO_FLAGS_NONCLEAR_RST);
+
+    if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
+        goto finish;
+    if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
+        goto finish;
+    if (!TEST_int_gt(BIO_reset(bio), 0))
+        goto finish;
+
+    if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
+        goto finish;
+    if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
+        goto finish;
+
+    BIO_clear_flags(bio, BIO_FLAGS_NONCLEAR_RST);
+    if (!TEST_int_gt(BIO_reset(bio), 0))
+        goto finish;
+
+    if (!TEST_int_lt(BIO_read(bio, data, 16), 1))
+        goto finish;
+
+    ok = 1;
+
+finish:
+    BIO_free(bio);
+    return ok;
+}
 
 int global_init(void)
 {
@@ -196,5 +235,6 @@ int setup_tests(void)
     ADD_TEST(test_bio_new_mem_buf);
     ADD_TEST(test_bio_rdonly_mem_buf);
     ADD_TEST(test_bio_rdwr_rdonly);
+    ADD_TEST(test_bio_nonclear_rst);
     return 1;
 }
index c68d7f6..0bd9a06 100644 (file)
@@ -2169,18 +2169,50 @@ static int test_expmodone(void)
     return ret;
 }
 
-static int test_smallprime(void)
+static int test_smallprime(int kBits)
 {
-    static const int kBits = 10;
     BIGNUM *r;
     int st = 0;
 
-    if (!TEST_ptr(r = BN_new())
-            || !TEST_true(BN_generate_prime_ex(r, (int)kBits, 0,
-                                               NULL, NULL, NULL))
-            || !TEST_int_eq(BN_num_bits(r), kBits))
+    if (!TEST_ptr(r = BN_new()))
+        goto err;
+
+    if (kBits <= 1) {
+        if (!TEST_false(BN_generate_prime_ex(r, kBits, 0,
+                                             NULL, NULL, NULL)))
+            goto err;
+    } else {
+        if (!TEST_true(BN_generate_prime_ex(r, kBits, 0,
+                                            NULL, NULL, NULL))
+                || !TEST_int_eq(BN_num_bits(r), kBits))
+            goto err;
+    }
+
+    st = 1;
+ err:
+    BN_free(r);
+    return st;
+}
+
+static int test_smallsafeprime(int kBits)
+{
+    BIGNUM *r;
+    int st = 0;
+
+    if (!TEST_ptr(r = BN_new()))
         goto err;
 
+    if (kBits <= 5 && kBits != 3) {
+        if (!TEST_false(BN_generate_prime_ex(r, kBits, 1,
+                                             NULL, NULL, NULL)))
+            goto err;
+    } else {
+        if (!TEST_true(BN_generate_prime_ex(r, kBits, 1,
+                                            NULL, NULL, NULL))
+                || !TEST_int_eq(BN_num_bits(r), kBits))
+            goto err;
+    }
+
     st = 1;
  err:
     BN_free(r);
@@ -2405,7 +2437,8 @@ int setup_tests(void)
         ADD_TEST(test_badmod);
         ADD_TEST(test_expmodzero);
         ADD_TEST(test_expmodone);
-        ADD_TEST(test_smallprime);
+        ADD_ALL_TESTS(test_smallprime, 16);
+        ADD_ALL_TESTS(test_smallsafeprime, 16);
         ADD_TEST(test_swap);
         ADD_TEST(test_ctx_consttime_flag);
 #ifndef OPENSSL_NO_EC2M
index a2fb0e2..1727f28 100644 (file)
@@ -12,7 +12,8 @@ IF[{- !$disabled{tests} -}]
   SOURCE[libtestutil.a]=testutil/basic_output.c testutil/output_helpers.c \
           testutil/driver.c testutil/tests.c testutil/cb.c testutil/stanza.c \
           testutil/format_output.c testutil/tap_bio.c \
-          testutil/test_cleanup.c testutil/main.c testutil/init.c
+          testutil/test_cleanup.c testutil/main.c testutil/init.c \
+          testutil/random.c
   INCLUDE[libtestutil.a]=../include
   DEPEND[libtestutil.a]=../libcrypto
 
index bf61548..ebb71c1 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/bash
 #
-# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 # Copyright (c) 2016 Viktor Dukhovni <openssl-users@dukhovni.org>.
 # All rights reserved.
 #
@@ -233,6 +233,35 @@ genee() {
            -set_serial 2 -days "${DAYS}" "$@"
 }
 
+geneenocsr() {
+    local OPTIND=1
+    local purpose=serverAuth
+
+    while getopts p: o
+    do
+        case $o in
+        p) purpose="$OPTARG";;
+        *) echo "Usage: $0 genee [-p EKU] cn certname cakeyname cacertname" >&2
+           return 1;;
+        esac
+    done
+
+    shift $((OPTIND - 1))
+    local cn=$1; shift
+    local cert=$1; shift
+    local cakey=$1; shift
+    local ca=$1; shift
+
+    exts=$(printf "%s\n%s\n%s\n%s\n%s\n[alts]\n%s\n" \
+           "subjectKeyIdentifier = hash" \
+           "authorityKeyIdentifier = keyid, issuer" \
+           "basicConstraints = CA:false" \
+           "extendedKeyUsage = $purpose" \
+           "subjectAltName = @alts" "DNS=${cn}")
+       cert "$cert" "$exts" -CA "${ca}.pem" -CAkey "${cakey}.pem" \
+           -set_serial 2 -days "${DAYS}" "$@"
+}
+
 genss() {
     local cn=$1; shift
     local key=$1; shift
diff --git a/test/certs/server-pss-restrict-cert.pem b/test/certs/server-pss-restrict-cert.pem
new file mode 100644 (file)
index 0000000..2733638
--- /dev/null
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDYjCCAkqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE5MDgwODEwNDMxMFoYDzIxMTkwODA5MTA0MzEwWjAUMRIwEAYDVQQD
+DAlsb2NhbGhvc3QwggFSMD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZIAWUDBAIBoRow
+GAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgA4IBDwAwggEKAoIBAQDDlygk
+sUEAajpdVquo9XIAyTd9ZJ+55hNmhBfhn3lHz3ryPD+0XlgCE9qsKwfR7iYaqmnN
+ilQnsxWpMGXAgOlC1+w5zh8qHvrI5wX+A6U9N8leIOSgFuFNP0FMMG7I677QzRxG
+FqKX1o4V73JWqnHCfnfHRyZY9xM0tYbJKNbRO7Hy4jKBPl3ptPHUoTltr4WYTOpg
+stcEamdiiif+0U4bQvVltNg9pzFEjkAktTUGn92W5CgLnsbPXxBo6a/kUlHcgmhY
+bpOXEjCPufZLgsQo8iF2Bq8eWMEsByjr0chQjzrfZAUVtD8Hmh2uMVAPQFAHUkaL
+j2tHukL+s9tAaWKNAgMBAAGjgY4wgYswHQYDVR0OBBYEFLqlLFaNrS8hbX6voiGi
+AfMYfsivMB8GA1UdIwQYMBaAFHB/Lq6DaFmYBCMqzes+F80k3QFJMAkGA1UdEwQC
+MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwKQYDVR0RBCIwIIIeU2VydmVyIFJTQS1Q
+U1MgcmVzdHJpY3RlZCBjZXJ0MA0GCSqGSIb3DQEBCwUAA4IBAQAEhm9Skn2XfEZo
+Q+YMu6HIQZovRT3IljHvesjIby7KfS86SU4r+CG7qaPLw7jeIR92YMnihnaXRGGJ
+POixpHY6gapEzR2Sqg7c0ApGenDZ3uKnBUjf9LEorPmhrEHUsnHREXoPx5Lt5Nh/
+7WRNB/GKvbnAby+5HQBOvU6P8t37/zK1JjJhGNv0uvaYthQGk3r6nEhQG+O6JBSw
+H/auU4ClIB4fg8GWaMuupN5VMNP9mxpL9tONH8QRKs+KIQWMOsr83rOKwSHrrkIL
+/vDI5hPj9RHvjjta6FQx140wA6c8ZB59x9YIv1alJWf6s3+TM8bv70L/aBBT8+IM
+vwjUz9Gp
+-----END CERTIFICATE-----
diff --git a/test/certs/server-pss-restrict-key.pem b/test/certs/server-pss-restrict-key.pem
new file mode 100644 (file)
index 0000000..6503226
--- /dev/null
@@ -0,0 +1,29 @@
+-----BEGIN PRIVATE KEY-----
+MIIE7wIBADA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3
+DQEBCDALBglghkgBZQMEAgGiAwIBIASCBKkwggSlAgEAAoIBAQDDlygksUEAajpd
+Vquo9XIAyTd9ZJ+55hNmhBfhn3lHz3ryPD+0XlgCE9qsKwfR7iYaqmnNilQnsxWp
+MGXAgOlC1+w5zh8qHvrI5wX+A6U9N8leIOSgFuFNP0FMMG7I677QzRxGFqKX1o4V
+73JWqnHCfnfHRyZY9xM0tYbJKNbRO7Hy4jKBPl3ptPHUoTltr4WYTOpgstcEamdi
+iif+0U4bQvVltNg9pzFEjkAktTUGn92W5CgLnsbPXxBo6a/kUlHcgmhYbpOXEjCP
+ufZLgsQo8iF2Bq8eWMEsByjr0chQjzrfZAUVtD8Hmh2uMVAPQFAHUkaLj2tHukL+
+s9tAaWKNAgMBAAECggEBAIzgfwWOtmb6HHfGSXY085wlUlZ696EKWsboNdtI5i4W
+/1Mimi/sFC/K5SJFDCjlA4UJYZOuItdFYkCun1t8foaqx3cLQ98u2SuDWwmOzqG9
+YMjvoDy+viDJgtrBt8n4I0R5t/ezrgD3hPe/s/dAZRfVx6g9Ux2ZOLgqV57kT3X7
+6paEz3jrIMvuoXQCsi9Qh+eJQ23/sAcc7OHQ7uD8QJVudEBnSHQ+ttvOPXhr7tba
+8NuNVa6E/KewkKHRAZqBTJolCVyPtWmvfaDwdJtunCvyR1w3Rv1adZLK4YRFz+vc
+sOMK+K1c2aojA+/Fnba19inNq13j6Dwqmq8Ho7MZwHECgYEA6aSx7/93S1VGpxQ9
+KqFE4Fy9ylliC/hanc9qOcfEIo0tDus9lfpuPp+aOXML0msVkIfhCnaru32qtnaI
+AQkIbPhSZFvC/i6BibpArXINbDzTS/46zZHehXskjWFGw+iRm/YI7MBuCmWzSnFO
+YUwSKRIPKZKyXswFzP8RsQO/QbsCgYEA1k5SamQheuKdo/X40ShWTTOoDlpL4Sir
+b2zTnEqlHyMv8c7w880hPf4P+0pqrKyf7jmEykJvp1qSAmyMUCWzrKTr8gQ2sMyb
+zj90cEm++M5YIQh5lPJy4pGqmCliJXqkt+zT1xmnRASwMNQOnU2bBmXkve/ofb4M
+dEwyig/nZFcCgYBLWPilTD6dhce+NBGxwMZkkKQIMKEk+RfIEs7QCXNgLSUdzZFT
+36pT+caTxl1Go5AVxyw04qZpVZKLO1iK9O3Jrp9rjAgrTrYpw23+QWzAvjDqLfeq
+ueMIKvlTus5GeacTo9mm+DvEkJ2sYTQEvrKQmilXn950IdmxDYUYD/xK5wKBgQDQ
+5ON9BUGFUSQsUHVLG7CT7EhiRS41ubjyEfhrHm+53Ei9weQpIcjHbsERR8aXrmTu
+h26i4QOI88XjSv+ymC19mfzLmcPdrnQpJL1RPvFCAZDyEhrBT1sg8rCBRcV/lv68
+scMEpuLecFt2HR5pwt3b7LJ9Wj8bYoctTaDt5va8XQKBgQDCr4hZB5haAcKmNm/g
+PjlaLdrDEIuuBjxMzX1t3PXwsEene1cE731v6fbmrDUa8AuJyMY80xhGrTTDQfS3
+QOu/6wtcUv/JC/06OwEaUlT/kdYek+zYfBm3b1sKP3HVKSxCLTcPcC4aQoAFqbEy
+3kuSVh03vVBdaP//qMPyeue17w==
+-----END PRIVATE KEY-----
index 53d4a80..26b2f1d 100755 (executable)
@@ -369,3 +369,9 @@ REQMASK=MASK:0x800 ./mkcert.sh req badalt7-key "O = Bad NC Test Certificate 7" \
 OPENSSL_KEYALG=ec OPENSSL_KEYBITS=brainpoolP256r1 ./mkcert.sh genee \
     "Server ECDSA brainpoolP256r1 cert" server-ecdsa-brainpoolP256r1-key \
     server-ecdsa-brainpoolP256r1-cert rootkey rootcert
+
+openssl req -new -nodes -subj "/CN=localhost" \
+    -newkey rsa-pss -keyout server-pss-restrict-key.pem \
+    -pkeyopt rsa_pss_keygen_md:sha256 -pkeyopt rsa_pss_keygen_saltlen:32 | \
+    ./mkcert.sh geneenocsr "Server RSA-PSS restricted cert" \
+    server-pss-restrict-cert rootkey rootcert
index ee02d9b..ff0319a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -141,7 +141,7 @@ static int test_check_null_numbers(void)
     }
 
     /*
-     * Verify that a NULL config with a missing envrionment variable returns
+     * Verify that a NULL config with a missing environment variable returns
      * a failure code.
      */
     if (!TEST_int_eq(unsetenv("FNORD"), 0)
index f881d5f..78d11ca 100644 (file)
@@ -87,29 +87,10 @@ static void tear_down(CT_TEST_FIXTURE *fixture)
     OPENSSL_free(fixture);
 }
 
-static char *mk_file_path(const char *dir, const char *file)
-{
-# ifndef OPENSSL_SYS_VMS
-    const char *sep = "/";
-# else
-    const char *sep = "";
-# endif
-    size_t len = strlen(dir) + strlen(sep) + strlen(file) + 1;
-    char *full_file = OPENSSL_zalloc(len);
-
-    if (full_file != NULL) {
-        OPENSSL_strlcpy(full_file, dir, len);
-        OPENSSL_strlcat(full_file, sep, len);
-        OPENSSL_strlcat(full_file, file, len);
-    }
-
-    return full_file;
-}
-
 static X509 *load_pem_cert(const char *dir, const char *file)
 {
     X509 *cert = NULL;
-    char *file_path = mk_file_path(dir, file);
+    char *file_path = test_mk_file_path(dir, file);
 
     if (file_path != NULL) {
         BIO *cert_io = BIO_new_file(file_path, "r");
@@ -127,7 +108,7 @@ static int read_text_file(const char *dir, const char *file,
                           char *buffer, int buffer_length)
 {
     int len = -1;
-    char *file_path = mk_file_path(dir, file);
+    char *file_path = test_mk_file_path(dir, file);
 
     if (file_path != NULL) {
         BIO *file_io = BIO_new_file(file_path, "r");
index 5b2fd67..9d5609b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -17,6 +17,7 @@
 #include <openssl/bn.h>
 #include <openssl/rand.h>
 #include <openssl/err.h>
+#include <openssl/obj_mac.h>
 #include "testutil.h"
 
 #ifndef OPENSSL_NO_DH
@@ -62,6 +63,17 @@ static int dh_test(void)
         || !TEST_true(DH_set0_pqg(dh, p, q, g)))
         goto err1;
 
+    if (!DH_check(dh, &i))
+        goto err2;
+    if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
+            || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
+            || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
+            || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
+            || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
+            || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
+            || !TEST_false(i))
+        goto err2;
+
     /* test the combined getter for p, q, and g */
     DH_get0_pqg(dh, &p2, &q2, &g2);
     if (!TEST_ptr_eq(p2, p)
@@ -130,7 +142,8 @@ static int dh_test(void)
     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
-            || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR))
+            || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
+            || !TEST_false(i))
         goto err3;
 
     DH_get0_pqg(a, &ap, NULL, &ag);
@@ -193,7 +206,7 @@ static int dh_test(void)
     BN_free(q);
     BN_free(g);
  err2:
-    /* an error occured before priv_key was assigned to dh */
+    /* an error occurred before priv_key was assigned to dh */
     BN_free(priv_key);
  err3:
  success:
@@ -609,6 +622,63 @@ static int rfc5114_test(void)
     TEST_error("Test failed RFC5114 set %d\n", i + 1);
     return 0;
 }
+
+static int rfc7919_test(void)
+{
+    DH *a = NULL, *b = NULL;
+    const BIGNUM *apub_key = NULL, *bpub_key = NULL;
+    unsigned char *abuf = NULL;
+    unsigned char *bbuf = NULL;
+    int i, alen, blen, aout, bout;
+    int ret = 0;
+
+    if (!TEST_ptr(a = DH_new_by_nid(NID_ffdhe2048)))
+         goto err;
+
+    if (!DH_check(a, &i))
+        goto err;
+    if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
+            || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
+            || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
+            || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
+            || !TEST_false(i))
+        goto err;
+
+    if (!DH_generate_key(a))
+        goto err;
+    DH_get0_key(a, &apub_key, NULL);
+
+    /* now create another copy of the DH group for the peer */
+    if (!TEST_ptr(b = DH_new_by_nid(NID_ffdhe2048)))
+        goto err;
+
+    if (!DH_generate_key(b))
+        goto err;
+    DH_get0_key(b, &bpub_key, NULL);
+
+    alen = DH_size(a);
+    if (!TEST_ptr(abuf = OPENSSL_malloc(alen))
+            || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
+        goto err;
+
+    blen = DH_size(b);
+    if (!TEST_ptr(bbuf = OPENSSL_malloc(blen))
+            || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
+        goto err;
+
+    if (!TEST_true(aout >= 20)
+            || !TEST_mem_eq(abuf, aout, bbuf, bout))
+        goto err;
+
+    ret = 1;
+
+ err:
+    OPENSSL_free(abuf);
+    OPENSSL_free(bbuf);
+    DH_free(a);
+    DH_free(b);
+    return ret;
+}
 #endif
 
 
@@ -619,6 +689,7 @@ int setup_tests(void)
 #else
     ADD_TEST(dh_test);
     ADD_TEST(rfc5114_test);
+    ADD_TEST(rfc7919_test);
 #endif
     return 1;
 }
index 0782a7c..7325e2f 100644 (file)
 # include <windows.h>
 #endif
 
+
+#if defined(OPENSSL_SYS_UNIX)
+# include <sys/types.h>
+# include <sys/wait.h>
+# include <unistd.h>
+#endif
+
 #include "testutil.h"
 #include "drbgtest.h"
 
@@ -293,7 +300,7 @@ static int error_check(DRBG_SELFTEST_DATA *td)
      * Personalisation string tests
      */
 
-    /* Test detection of too large personlisation string */
+    /* Test detection of too large personalisation string */
     if (!init(drbg, td, &t)
             || RAND_DRBG_instantiate(drbg, td->pers, drbg->max_perslen + 1) > 0)
         goto err;
@@ -669,6 +676,40 @@ static int test_drbg_reseed(int expect_success,
     return 1;
 }
 
+
+#if defined(OPENSSL_SYS_UNIX)
+/*
+ * Test whether master, public and private DRBG are reseeded after
+ * forking the process.
+ */
+static int test_drbg_reseed_after_fork(RAND_DRBG *master,
+                                       RAND_DRBG *public,
+                                       RAND_DRBG *private)
+{
+    pid_t pid;
+    int status=0;
+
+    pid = fork();
+    if (!TEST_int_ge(pid, 0))
+        return 0;
+
+    if (pid > 0) {
+        /* I'm the parent; wait for the child and check its exit code */
+        return TEST_int_eq(waitpid(pid, &status, 0), pid) && TEST_int_eq(status, 0);
+    }
+
+    /* I'm the child; check whether all three DRBGs reseed. */
+    if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1, 0)))
+        status = 1;
+
+    /* Remove hooks  */
+    unhook_drbg(master);
+    unhook_drbg(public);
+    unhook_drbg(private);
+    exit(status);
+}
+#endif
+
 /*
  * Test whether the default rand_method (RAND_OpenSSL()) is
  * setup correctly, in particular whether reseeding  works
@@ -755,6 +796,10 @@ static int test_rand_drbg_reseed(void)
         goto error;
     reset_drbg_hook_ctx();
 
+#if defined(OPENSSL_SYS_UNIX)
+    if (!TEST_true(test_drbg_reseed_after_fork(master, public, private)))
+        goto error;
+#endif
 
     /* fill 'randomness' buffer with some arbitrary data */
     memset(rand_add_buf, 'r', sizeof(rand_add_buf));
index 9e6ed44..ab4d4c1 100644 (file)
@@ -96,7 +96,7 @@ static int test_dtls_unprocessed(int testidx)
 
     /*
      * Create the connection. We use "create_bare_ssl_connection" here so that
-     * we can force the connection to not do "SSL_read" once partly conencted.
+     * we can force the connection to not do "SSL_read" once partly connected.
      * We don't want to accidentally read the dummy records we injected because
      * they will fail to decrypt.
      */
index 269ec4e..136dc74 100644 (file)
@@ -1519,6 +1519,271 @@ static const unsigned char p521_explicit[] = {
     0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
 };
 
+/*
+ * Sometime we cannot compare nids for equality, as the built-in curve table
+ * includes aliases with different names for the same curve.
+ *
+ * This function returns TRUE (1) if the checked nids are identical, or if they
+ * alias to the same curve. FALSE (0) otherwise.
+ */
+static ossl_inline
+int are_ec_nids_compatible(int n1d, int n2d)
+{
+    int ret = 0;
+    switch (n1d) {
+# ifndef OPENSSL_NO_EC2M
+        case NID_sect113r1:
+        case NID_wap_wsg_idm_ecid_wtls4:
+            ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
+            break;
+        case NID_sect163k1:
+        case NID_wap_wsg_idm_ecid_wtls3:
+            ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
+            break;
+        case NID_sect233k1:
+        case NID_wap_wsg_idm_ecid_wtls10:
+            ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
+            break;
+        case NID_sect233r1:
+        case NID_wap_wsg_idm_ecid_wtls11:
+            ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
+            break;
+        case NID_X9_62_c2pnb163v1:
+        case NID_wap_wsg_idm_ecid_wtls5:
+            ret = (n2d == NID_X9_62_c2pnb163v1
+                   || n2d == NID_wap_wsg_idm_ecid_wtls5);
+            break;
+# endif /* OPENSSL_NO_EC2M */
+        case NID_secp112r1:
+        case NID_wap_wsg_idm_ecid_wtls6:
+            ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
+            break;
+        case NID_secp160r2:
+        case NID_wap_wsg_idm_ecid_wtls7:
+            ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
+            break;
+# ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
+        case NID_secp224r1:
+        case NID_wap_wsg_idm_ecid_wtls12:
+            ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
+            break;
+# else
+        /*
+         * For SEC P-224 we want to ensure that the SECP nid is returned, as
+         * that is associated with a specialized method.
+         */
+        case NID_wap_wsg_idm_ecid_wtls12:
+            ret = (n2d == NID_secp224r1);
+            break;
+# endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
+
+        default:
+            ret = (n1d == n2d);
+    }
+    return ret;
+}
+
+/*
+ * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
+ * EC_GROUP for built-in curves.
+ *
+ * Note that it is possible to retrieve an alternative alias that does not match
+ * the original nid.
+ *
+ * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
+ */
+static int check_named_curve_from_ecparameters(int id)
+{
+    int ret = 0, nid, tnid;
+    EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
+    const EC_POINT *group_gen = NULL;
+    EC_POINT *other_gen = NULL;
+    BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
+    BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
+    const BIGNUM *group_order = NULL;
+    BIGNUM *other_order = NULL;
+    BN_CTX *bn_ctx = NULL;
+    static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
+    static size_t invalid_seed_len = sizeof(invalid_seed);
+    ECPARAMETERS *params = NULL, *other_params = NULL;
+    EC_GROUP *g_ary[8] = {NULL};
+    EC_GROUP **g_next = &g_ary[0];
+    ECPARAMETERS *p_ary[8] = {NULL};
+    ECPARAMETERS **p_next = &p_ary[0];
+
+    /* Do some setup */
+    nid = curves[id].nid;
+    TEST_note("Curve %s", OBJ_nid2sn(nid));
+    if (!TEST_ptr(bn_ctx = BN_CTX_new()))
+        return ret;
+    BN_CTX_start(bn_ctx);
+
+    if (/* Allocations */
+        !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
+        || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
+        || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
+        || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
+        || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
+        /* Generate reference group and params */
+        || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
+        || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
+        || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
+        || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
+        || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
+        /* compute `other_*` values */
+        || !TEST_ptr(tmpg = EC_GROUP_dup(group))
+        || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
+        || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
+        || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
+                      other_gen_x, other_gen_y, bn_ctx))
+        || !TEST_true(BN_copy(other_order, group_order))
+        || !TEST_true(BN_add_word(other_order, 1))
+        || !TEST_true(BN_copy(other_cofactor, group_cofactor))
+        || !TEST_true(BN_add_word(other_cofactor, 1)))
+        goto err;
+
+    EC_POINT_free(other_gen);
+    other_gen = NULL;
+
+    if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
+        || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
+                                                      other_gen_x, other_gen_y,
+                                                      bn_ctx)))
+        goto err;
+
+    /*
+     * ###########################
+     * # Actual tests start here #
+     * ###########################
+     */
+
+    /*
+     * Creating a group from built-in explicit parameters returns a
+     * "named" EC_GROUP
+     */
+    if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
+        || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
+        goto err;
+    /*
+     * We cannot always guarantee the names match, as the built-in table
+     * contains aliases for the same curve with different names.
+     */
+    if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
+        TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
+        goto err;
+    }
+    /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
+    if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
+        goto err;
+
+    /*
+     * An invalid seed in the parameters should be ignored: expect a "named"
+     * group.
+     */
+    if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
+                     invalid_seed_len)
+            || !TEST_ptr(other_params = *p_next++ =
+                         EC_GROUP_get_ecparameters(tmpg, NULL))
+            || !TEST_ptr(tgroup = *g_next++ =
+                          EC_GROUP_new_from_ecparameters(other_params))
+            || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
+            || !TEST_true(are_ec_nids_compatible(nid, tnid))
+            || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
+                            OPENSSL_EC_EXPLICIT_CURVE)) {
+        TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
+        goto err;
+    }
+
+    /*
+     * A null seed in the parameters should be ignored, as it is optional:
+     * expect a "named" group.
+     */
+    if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
+            || !TEST_ptr(other_params = *p_next++ =
+                         EC_GROUP_get_ecparameters(tmpg, NULL))
+            || !TEST_ptr(tgroup = *g_next++ =
+                          EC_GROUP_new_from_ecparameters(other_params))
+            || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
+            || !TEST_true(are_ec_nids_compatible(nid, tnid))
+            || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
+                            OPENSSL_EC_EXPLICIT_CURVE)) {
+        TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
+        goto err;
+    }
+
+    /*
+     * Check that changing any of the generator parameters does not yield a
+     * match with the built-in curves
+     */
+    if (/* Other gen, same group order & cofactor */
+        !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
+                                          group_cofactor))
+        || !TEST_ptr(other_params = *p_next++ =
+                     EC_GROUP_get_ecparameters(tmpg, NULL))
+        || !TEST_ptr(tgroup = *g_next++ =
+                      EC_GROUP_new_from_ecparameters(other_params))
+        || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
+        /* Same gen & cofactor, different order */
+        || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
+                                             group_cofactor))
+        || !TEST_ptr(other_params = *p_next++ =
+                     EC_GROUP_get_ecparameters(tmpg, NULL))
+        || !TEST_ptr(tgroup = *g_next++ =
+                      EC_GROUP_new_from_ecparameters(other_params))
+        || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
+        /* The order is not an optional field, so this should fail */
+        || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
+                                              group_cofactor))
+        /* Check that a wrong cofactor is ignored, and we still match */
+        || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
+                                             other_cofactor))
+        || !TEST_ptr(other_params = *p_next++ =
+                     EC_GROUP_get_ecparameters(tmpg, NULL))
+        || !TEST_ptr(tgroup = *g_next++ =
+                      EC_GROUP_new_from_ecparameters(other_params))
+        || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
+        || !TEST_true(are_ec_nids_compatible(nid, tnid))
+        || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
+                        OPENSSL_EC_EXPLICIT_CURVE)
+        /* Check that if the cofactor is not set then it still matches */
+        || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
+                                             NULL))
+        || !TEST_ptr(other_params = *p_next++ =
+                     EC_GROUP_get_ecparameters(tmpg, NULL))
+        || !TEST_ptr(tgroup = *g_next++ =
+                      EC_GROUP_new_from_ecparameters(other_params))
+        || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
+        || !TEST_true(are_ec_nids_compatible(nid, tnid))
+        || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
+                        OPENSSL_EC_EXPLICIT_CURVE)
+        /* check that restoring the generator passes */
+        || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
+                                             group_cofactor))
+        || !TEST_ptr(other_params = *p_next++ =
+                     EC_GROUP_get_ecparameters(tmpg, NULL))
+        || !TEST_ptr(tgroup = *g_next++ =
+                      EC_GROUP_new_from_ecparameters(other_params))
+        || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
+        || !TEST_true(are_ec_nids_compatible(nid, tnid))
+        || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
+                        OPENSSL_EC_EXPLICIT_CURVE))
+        goto err;
+
+    ret = 1;
+err:
+    for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
+        EC_GROUP_free(*g_next);
+    for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
+        ECPARAMETERS_free(*p_next);
+    ECPARAMETERS_free(params);
+    EC_POINT_free(other_gen);
+    EC_GROUP_free(tmpg);
+    EC_GROUP_free(group);
+    BN_CTX_end(bn_ctx);
+    BN_CTX_free(bn_ctx);
+    return ret;
+}
+
 static int parameter_test(void)
 {
     EC_GROUP *group = NULL, *group2 = NULL;
@@ -1561,6 +1826,179 @@ err:
     OPENSSL_free(buf);
     return r;
 }
+
+/*-
+ * random 256-bit explicit parameters curve, cofactor absent
+ * order:    0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
+ * cofactor:   0x12bc94785251297abfafddf1565100da (125 bit)
+ */
+static const unsigned char params_cf_pass[] = {
+    0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
+    0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
+    0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
+    0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
+    0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
+    0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
+    0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
+    0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
+    0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
+    0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
+    0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
+    0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
+    0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
+    0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
+    0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
+    0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
+    0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
+    0x14, 0xa8, 0x2f, 0x4f
+};
+
+/*-
+ * random 256-bit explicit parameters curve, cofactor absent
+ * order:    0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
+ * cofactor:   0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
+ */
+static const unsigned char params_cf_fail[] = {
+    0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
+    0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
+    0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
+    0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
+    0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
+    0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
+    0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
+    0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
+    0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
+    0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
+    0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
+    0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
+    0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
+    0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
+    0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
+    0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
+    0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
+    0x34, 0xa2, 0x21, 0x01
+};
+
+/*-
+ * Test two random 256-bit explicit parameters curves with absent cofactor.
+ * The two curves are chosen to roughly straddle the bounds at which the lib
+ * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
+ *
+ * - params_cf_pass: order is sufficiently close to p to compute cofactor
+ * - params_cf_fail: order is too far away from p to compute cofactor
+ *
+ * For standards-compliant curves, cofactor is chosen as small as possible.
+ * So you can see neither of these curves are fit for cryptographic use.
+ *
+ * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
+ * h <= 2**(t/8) where t is the security level of the curve, for which the lib
+ * will always succeed in computing the cofactor. Neither of these curves
+ * conform to that -- this is just robustness testing.
+ */
+static int cofactor_range_test(void)
+{
+    EC_GROUP *group = NULL;
+    BIGNUM *cf = NULL;
+    int ret = 0;
+    const unsigned char *b1 = (const unsigned char *)params_cf_fail;
+    const unsigned char *b2 = (const unsigned char *)params_cf_pass;
+
+    if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
+        || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
+        || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
+                                                sizeof(params_cf_pass)))
+        || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
+        || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
+        goto err;
+    ret = 1;
+ err:
+    BN_free(cf);
+    EC_GROUP_free(group);
+    return ret;
+}
+
+/*-
+ * For named curves, test that:
+ * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
+ * - a nonsensical cofactor throws an error (negative test)
+ * - nonsensical orders throw errors (negative tests)
+ */
+static int cardinality_test(int n)
+{
+    int ret = 0;
+    int nid = curves[n].nid;
+    BN_CTX *ctx = NULL;
+    EC_GROUP *g1 = NULL, *g2 = NULL;
+    EC_POINT *g2_gen = NULL;
+    BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
+           *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
+
+    TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
+
+    if (!TEST_ptr(ctx = BN_CTX_new())
+        || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))
+        || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) {
+        EC_GROUP_free(g1);
+        EC_GROUP_free(g2);
+        BN_CTX_free(ctx);
+        return 0;
+    }
+
+    BN_CTX_start(ctx);
+    g1_p = BN_CTX_get(ctx);
+    g1_a = BN_CTX_get(ctx);
+    g1_b = BN_CTX_get(ctx);
+    g1_x = BN_CTX_get(ctx);
+    g1_y = BN_CTX_get(ctx);
+    g1_order = BN_CTX_get(ctx);
+    g1_cf = BN_CTX_get(ctx);
+
+    if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
+        /* pull out the explicit curve parameters */
+        || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
+        || !TEST_true(EC_POINT_get_affine_coordinates(g1,
+                      EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
+        || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
+        || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
+        /* construct g2 manually with g1 parameters */
+        || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx))
+        || !TEST_ptr(g2_gen = EC_POINT_new(g2))
+        || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
+        /* pass NULL cofactor: lib should compute it */
+        || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
+        || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
+        || !TEST_BN_eq(g1_cf, g2_cf)
+        /* pass zero cofactor: lib should compute it */
+        || !TEST_true(BN_set_word(g2_cf, 0))
+        || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
+        || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
+        || !TEST_BN_eq(g1_cf, g2_cf)
+        /* negative test for invalid cofactor */
+        || !TEST_true(BN_set_word(g2_cf, 0))
+        || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
+        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
+        /* negative test for NULL order */
+        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
+        /* negative test for zero order */
+        || !TEST_true(BN_set_word(g1_order, 0))
+        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
+        /* negative test for negative order */
+        || !TEST_true(BN_set_word(g2_cf, 0))
+        || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
+        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
+        /* negative test for too large order */
+        || !TEST_true(BN_lshift(g1_order, g1_p, 2))
+        || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
+        goto err;
+    ret = 1;
+ err:
+    EC_POINT_free(g2_gen);
+    EC_GROUP_free(g1);
+    EC_GROUP_free(g2);
+    BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    return ret;
+}
 #endif
 
 int setup_tests(void)
@@ -1572,6 +2010,8 @@ int setup_tests(void)
         return 0;
 
     ADD_TEST(parameter_test);
+    ADD_TEST(cofactor_range_test);
+    ADD_ALL_TESTS(cardinality_test, crv_len);
     ADD_TEST(prime_field_tests);
 # ifndef OPENSSL_NO_EC2M
     ADD_TEST(char2_field_tests);
@@ -1583,7 +2023,9 @@ int setup_tests(void)
 # endif
     ADD_ALL_TESTS(internal_curve_test, crv_len);
     ADD_ALL_TESTS(internal_curve_test_method, crv_len);
-#endif
+
+    ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
+#endif /* OPENSSL_NO_EC */
     return 1;
 }
 
index be57f16..c3dc5bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -120,8 +120,12 @@ static int test_engines(void)
     display_engine_list();
 
     /*
-     * Depending on whether there's any hardware support compiled in, this
-     * remove may be destined to fail.
+     * At this point, we should have an empty list, unless some hardware
+     * support engine got added.  However, since we don't allow the config
+     * file to be loaded and don't otherwise load any built in engines,
+     * that is unlikely.  Still, we check, if for nothing else, then to
+     * notify that something is a little off (and might mean that |new_h1|
+     * wasn't unloaded when it should have)
      */
     if ((ptr = ENGINE_get_first()) != NULL) {
         if (!ENGINE_remove(ptr))
@@ -346,6 +350,15 @@ static int test_redirect(void)
 }
 #endif
 
+int global_init(void)
+{
+    /*
+     * If the config file gets loaded, the dynamic engine will be loaded,
+     * and that interferes with our test above.
+     */
+    return OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG, NULL);
+}
+
 int setup_tests(void)
 {
 #ifdef OPENSSL_NO_ENGINE
index 8277f95..3ae6408 100644 (file)
@@ -300,7 +300,7 @@ static const unsigned char kExampleECPubKeyDER[] = {
 };
 
 /*
- * kExampleBadECKeyDER is a sample EC public key with a wrong OID
+ * kExampleBadECPubKeyDER is a sample EC public key with a wrong OID
  * 1.2.840.10045.2.2 instead of 1.2.840.10045.2.1 - EC Public Key
  */
 static const unsigned char kExampleBadECPubKeyDER[] = {
index 7a3e41c..abb5138 100644 (file)
@@ -403,6 +403,28 @@ static int digest_test_run(EVP_TEST *t)
     }
 
     if (EVP_MD_flags(expected->digest) & EVP_MD_FLAG_XOF) {
+        EVP_MD_CTX *mctx_cpy;
+        char dont[] = "touch";
+
+        if (!TEST_ptr(mctx_cpy = EVP_MD_CTX_new())) {
+            goto err;
+        }
+        if (!EVP_MD_CTX_copy(mctx_cpy, mctx)) {
+            EVP_MD_CTX_free(mctx_cpy);
+            goto err;
+        }
+        if (!EVP_DigestFinalXOF(mctx_cpy, (unsigned char *)dont, 0)) {
+            EVP_MD_CTX_free(mctx_cpy);
+            t->err = "DIGESTFINALXOF_ERROR";
+            goto err;
+        }
+        if (!TEST_str_eq(dont, "touch")) {
+            EVP_MD_CTX_free(mctx_cpy);
+            t->err = "DIGESTFINALXOF_ERROR";
+            goto err;
+        }
+        EVP_MD_CTX_free(mctx_cpy);
+
         got_len = expected->output_len;
         if (!EVP_DigestFinalXOF(mctx, got, got_len)) {
             t->err = "DIGESTFINALXOF_ERROR";
@@ -532,7 +554,7 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword,
             else if (strcmp(value, "FALSE") == 0)
                 cdat->tag_late = 0;
             else
-                return 0;
+                return -1;
             return 1;
         }
     }
@@ -543,7 +565,7 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword,
         else if (strcmp(value, "DECRYPT") == 0)
             cdat->enc = 0;
         else
-            return 0;
+            return -1;
         return 1;
     }
     return 0;
@@ -923,7 +945,7 @@ static int mac_test_parse(EVP_TEST *t,
     if (strcmp(keyword, "Algorithm") == 0) {
         mdata->alg = OPENSSL_strdup(value);
         if (!mdata->alg)
-            return 0;
+            return -1;
         return 1;
     }
     if (strcmp(keyword, "Input") == 0)
@@ -1270,9 +1292,9 @@ static int pderive_test_parse(EVP_TEST *t,
     if (strcmp(keyword, "PeerKey") == 0) {
         EVP_PKEY *peer;
         if (find_key(&peer, value, public_keys) == 0)
-            return 0;
+            return -1;
         if (EVP_PKEY_derive_set_peer(kdata->ctx, peer) <= 0)
-            return 0;
+            return -1;
         return 1;
     }
     if (strcmp(keyword, "SharedSecret") == 0)
@@ -2120,7 +2142,7 @@ static int digestsigver_test_parse(EVP_TEST *t,
     }
     if (strcmp(keyword, "Ctrl") == 0) {
         if (mdata->pctx == NULL)
-            return 0;
+            return -1;
         return pkey_test_ctrl(t, mdata->pctx, value);
     }
     return 0;
index 68eddca..29c317a 100644 (file)
@@ -1190,7 +1190,18 @@ Result = CIPHERFINAL_ERROR
 
 Title = AES XTS test vectors from IEEE Std 1619-2007
 
+# Using the same key twice for encryption is always banned.
 Cipher = aes-128-xts
+Operation = ENCRYPT
+Key = 0000000000000000000000000000000000000000000000000000000000000000
+IV = 00000000000000000000000000000000
+Plaintext = 0000000000000000000000000000000000000000000000000000000000000000
+Ciphertext = 917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e
+Result = KEY_SET_ERROR
+
+# Using the same key twice for decryption is allowed outside of FIPS mode.
+Cipher = aes-128-xts
+Operation = DECRYPT
 Key = 0000000000000000000000000000000000000000000000000000000000000000
 IV = 00000000000000000000000000000000
 Plaintext = 0000000000000000000000000000000000000000000000000000000000000000
index 1e46769..212791f 100644 (file)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -95,58 +95,81 @@ my $proxy = TLSProxy::Proxy->new(
 
 @extensions = (
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SERVER_NAME_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
+        TLSProxy::Message::CLIENT,
         checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
     (disabled("ec") ? () :
                       [TLSProxy::Message::MT_CLIENT_HELLO,
                        TLSProxy::Message::EXT_SUPPORTED_GROUPS,
+                       TLSProxy::Message::CLIENT,
                        checkhandshake::DEFAULT_EXTENSIONS]),
     (disabled("ec") ? () :
                       [TLSProxy::Message::MT_CLIENT_HELLO,
                        TLSProxy::Message::EXT_EC_POINT_FORMATS,
+                       TLSProxy::Message::CLIENT,
                        checkhandshake::DEFAULT_EXTENSIONS]),
     (disabled("tls1_2") ? () :
      [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
+        TLSProxy::Message::CLIENT,
          checkhandshake::DEFAULT_EXTENSIONS]),
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
+        TLSProxy::Message::CLIENT,
         checkhandshake::ALPN_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SCT_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE,
+        TLSProxy::Message::CLIENT,
         checkhandshake::RENEGOTIATE_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_NPN,
+        TLSProxy::Message::CLIENT,
         checkhandshake::NPN_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SRP,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SRP_CLI_EXTENSION],
 
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_RENEGOTIATE,
+        TLSProxy::Message::SERVER,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
+        TLSProxy::Message::SERVER,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
+        TLSProxy::Message::SERVER,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
+        TLSProxy::Message::SERVER,
         checkhandshake::SESSION_TICKET_SRV_EXTENSION],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
+        TLSProxy::Message::SERVER,
         checkhandshake::SERVER_NAME_SRV_EXTENSION],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
+        TLSProxy::Message::SERVER,
         checkhandshake::STATUS_REQUEST_SRV_EXTENSION],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_ALPN,
+        TLSProxy::Message::SERVER,
         checkhandshake::ALPN_SRV_EXTENSION],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SCT,
+        TLSProxy::Message::SERVER,
         checkhandshake::SCT_SRV_EXTENSION],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_NPN,
+        TLSProxy::Message::SERVER,
         checkhandshake::NPN_SRV_EXTENSION],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
+        TLSProxy::Message::SERVER,
         checkhandshake::EC_POINT_FORMAT_SRV_EXTENSION],
-    [0,0,0]
+    [0,0,0,0]
 );
 
 #Test 1: Check we get all the right messages for a default handshake
index 716e260..98989b4 100644 (file)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -62,78 +62,112 @@ $ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf");
 
 @extensions = (
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SERVER_NAME_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
+        TLSProxy::Message::CLIENT,
         checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
+        TLSProxy::Message::CLIENT,
         checkhandshake::ALPN_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SCT_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
+        TLSProxy::Message::CLIENT,
         checkhandshake::PSK_KEX_MODES_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
+        TLSProxy::Message::CLIENT,
         checkhandshake::PSK_CLI_EXTENSION],
 
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
+        TLSProxy::Message::SERVER,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
+        TLSProxy::Message::SERVER,
         checkhandshake::KEY_SHARE_HRR_EXTENSION],
 
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SERVER_NAME_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
+        TLSProxy::Message::CLIENT,
         checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
+        TLSProxy::Message::CLIENT,
         checkhandshake::ALPN_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SCT_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
+        TLSProxy::Message::CLIENT,
         checkhandshake::PSK_KEX_MODES_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
+        TLSProxy::Message::CLIENT,
         checkhandshake::PSK_CLI_EXTENSION],
 
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
+        TLSProxy::Message::SERVER,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
+        TLSProxy::Message::SERVER,
         checkhandshake::KEY_SHARE_SRV_EXTENSION],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK,
+        TLSProxy::Message::SERVER,
         checkhandshake::PSK_SRV_EXTENSION],
 
     [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST,
+        TLSProxy::Message::SERVER,
         checkhandshake::STATUS_REQUEST_SRV_EXTENSION],
-    [0,0,0]
+    [0,0,0,0]
 );
 
 use constant {
index be6a2db..171a12f 100644 (file)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -62,92 +62,136 @@ $ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf");
 
 @extensions = (
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SERVER_NAME_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
+        TLSProxy::Message::CLIENT,
         checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
+        TLSProxy::Message::CLIENT,
         checkhandshake::ALPN_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SCT_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
+        TLSProxy::Message::CLIENT,
         checkhandshake::PSK_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH,
+        TLSProxy::Message::CLIENT,
         checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION],
 
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
+        TLSProxy::Message::SERVER,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
+        TLSProxy::Message::SERVER,
         checkhandshake::KEY_SHARE_HRR_EXTENSION],
 
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SERVER_NAME_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
+        TLSProxy::Message::CLIENT,
         checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
+        TLSProxy::Message::CLIENT,
         checkhandshake::ALPN_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
+        TLSProxy::Message::CLIENT,
         checkhandshake::SCT_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
+        TLSProxy::Message::CLIENT,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
+        TLSProxy::Message::CLIENT,
         checkhandshake::PSK_CLI_EXTENSION],
     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH,
+        TLSProxy::Message::CLIENT,
         checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION],
 
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
+        TLSProxy::Message::SERVER,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
+        TLSProxy::Message::SERVER,
         checkhandshake::DEFAULT_EXTENSIONS],
     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK,
+        TLSProxy::Message::SERVER,
         checkhandshake::PSK_SRV_EXTENSION],
 
     [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SERVER_NAME,
+        TLSProxy::Message::SERVER,
         checkhandshake::SERVER_NAME_SRV_EXTENSION],
     [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_ALPN,
+        TLSProxy::Message::SERVER,
         checkhandshake::ALPN_SRV_EXTENSION],
     [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
+        TLSProxy::Message::SERVER,
         checkhandshake::SUPPORTED_GROUPS_SRV_EXTENSION],
 
+    [TLSProxy::Message::MT_CERTIFICATE_REQUEST, TLSProxy::Message::EXT_SIG_ALGS,
+        TLSProxy::Message::SERVER,
+        checkhandshake::DEFAULT_EXTENSIONS],
+
     [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST,
+        TLSProxy::Message::SERVER,
         checkhandshake::STATUS_REQUEST_SRV_EXTENSION],
     [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_SCT,
+        TLSProxy::Message::SERVER,
         checkhandshake::SCT_SRV_EXTENSION],
 
-    [0,0,0]
+    [0,0,0,0]
 );
 
 my $proxy = TLSProxy::Proxy->new(
@@ -163,7 +207,7 @@ $proxy->serverconnects(2);
 $proxy->clientflags("-sess_out ".$session);
 $proxy->sessionfile($session);
 $proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
-plan tests => 16;
+plan tests => 17;
 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
                checkhandshake::DEFAULT_EXTENSIONS,
                "Default handshake test");
@@ -179,7 +223,7 @@ checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
                "Resumption handshake test");
 
 SKIP: {
-    skip "No OCSP support in this OpenSSL build", 3
+    skip "No OCSP support in this OpenSSL build", 4
         if disabled("ct") || disabled("ec") || disabled("ocsp");
     #Test 3: A status_request handshake (client request only)
     $proxy->clear();
@@ -210,9 +254,23 @@ SKIP: {
                    | checkhandshake::STATUS_REQUEST_CLI_EXTENSION
                    | checkhandshake::STATUS_REQUEST_SRV_EXTENSION,
                    "status_request handshake test");
+
+    #Test 6: A status_request handshake (client and server) with client auth
+    $proxy->clear();
+    $proxy->clientflags("-status -enable_pha -cert "
+                        .srctop_file("apps", "server.pem"));
+    $proxy->serverflags("-Verify 5 -status_file "
+                        .srctop_file("test", "recipes", "ocsp-response.der"));
+    $proxy->start();
+    checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
+                   checkhandshake::DEFAULT_EXTENSIONS
+                   | checkhandshake::STATUS_REQUEST_CLI_EXTENSION
+                   | checkhandshake::STATUS_REQUEST_SRV_EXTENSION
+                   | checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION,
+                   "status_request handshake with client auth test");
 }
 
-#Test 6: A client auth handshake
+#Test 7: A client auth handshake
 $proxy->clear();
 $proxy->clientflags("-enable_pha -cert ".srctop_file("apps", "server.pem"));
 $proxy->serverflags("-Verify 5");
@@ -222,7 +280,7 @@ checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
                checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION,
                "Client auth handshake test");
 
-#Test 7: Server name handshake (no client request)
+#Test 8: Server name handshake (no client request)
 $proxy->clear();
 $proxy->clientflags("-noservername");
 $proxy->start();
@@ -231,7 +289,7 @@ checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
                & ~checkhandshake::SERVER_NAME_CLI_EXTENSION,
                "Server name handshake test (client)");
 
-#Test 8: Server name handshake (server support only)
+#Test 9: Server name handshake (server support only)
 $proxy->clear();
 $proxy->clientflags("-noservername");
 $proxy->serverflags("-servername testhost");
@@ -241,7 +299,7 @@ checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
                & ~checkhandshake::SERVER_NAME_CLI_EXTENSION,
                "Server name handshake test (server)");
 
-#Test 9: Server name handshake (client and server)
+#Test 10: Server name handshake (client and server)
 $proxy->clear();
 $proxy->clientflags("-servername testhost");
 $proxy->serverflags("-servername testhost");
@@ -251,7 +309,7 @@ checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
                | checkhandshake::SERVER_NAME_SRV_EXTENSION,
                "Server name handshake test");
 
-#Test 10: ALPN handshake (client request only)
+#Test 11: ALPN handshake (client request only)
 $proxy->clear();
 $proxy->clientflags("-alpn test");
 $proxy->start();
@@ -260,7 +318,7 @@ checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
                | checkhandshake::ALPN_CLI_EXTENSION,
                "ALPN handshake test (client)");
 
-#Test 11: ALPN handshake (server support only)
+#Test 12: ALPN handshake (server support only)
 $proxy->clear();
 $proxy->serverflags("-alpn test");
 $proxy->start();
@@ -268,7 +326,7 @@ checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
                checkhandshake::DEFAULT_EXTENSIONS,
                "ALPN handshake test (server)");
 
-#Test 12: ALPN handshake (client and server)
+#Test 13: ALPN handshake (client and server)
 $proxy->clear();
 $proxy->clientflags("-alpn test");
 $proxy->serverflags("-alpn test");
@@ -283,7 +341,7 @@ SKIP: {
     skip "No CT, EC or OCSP support in this OpenSSL build", 1
         if disabled("ct") || disabled("ec") || disabled("ocsp");
 
-    #Test 13: SCT handshake (client request only)
+    #Test 14: SCT handshake (client request only)
     $proxy->clear();
     #Note: -ct also sends status_request
     $proxy->clientflags("-ct");
@@ -300,10 +358,7 @@ SKIP: {
                    "SCT handshake test");
 }
 
-
-
-
-#Test 14: HRR Handshake
+#Test 15: HRR Handshake
 $proxy->clear();
 $proxy->serverflags("-curves P-256");
 $proxy->start();
@@ -312,7 +367,7 @@ checkhandshake($proxy, checkhandshake::HRR_HANDSHAKE,
                | checkhandshake::KEY_SHARE_HRR_EXTENSION,
                "HRR handshake test");
 
-#Test 15: Resumption handshake with HRR
+#Test 16: Resumption handshake with HRR
 $proxy->clear();
 $proxy->clientflags("-sess_in ".$session);
 $proxy->serverflags("-curves P-256");
@@ -324,7 +379,7 @@ checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
                 | checkhandshake::PSK_SRV_EXTENSION),
                "Resumption handshake with HRR test");
 
-#Test 16: Acceptable but non preferred key_share
+#Test 17: Acceptable but non preferred key_share
 $proxy->clear();
 $proxy->clientflags("-curves P-256");
 $proxy->start();
index b57ca66..5dc6a3a 100644 (file)
@@ -21,12 +21,13 @@ setup("test_cms");
 plan skip_all => "CMS is not supported by this OpenSSL build"
     if disabled("cms");
 
+my $datadir = srctop_dir("test", "recipes", "80-test_cms_data");
 my $smdir    = srctop_dir("test", "smime-certs");
 my $smcont   = srctop_file("test", "smcont.txt");
 my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
     = disabled qw/des dh dsa ec ec2m rc2 zlib/;
 
-plan tests => 4;
+plan tests => 6;
 
 my @smime_pkcs7_tests = (
 
@@ -400,6 +401,26 @@ my @smime_cms_param_tests = (
     ]
     );
 
+my @contenttype_cms_test = (
+    [ "signed content test - check that content type is added to additional signerinfo, RSA keys",
+      [ "-sign", "-binary", "-nodetach", "-stream", "-in", $smcont, "-outform", "DER",
+        "-signer", catfile($smdir, "smrsa1.pem"), "-md", "SHA256",
+        "-out", "test.cms" ],
+      [ "-resign", "-binary", "-nodetach", "-in", "test.cms", "-inform", "DER", "-outform", "DER",
+        "-signer", catfile($smdir, "smrsa2.pem"), "-md", "SHA256",
+        "-out", "test2.cms" ],
+      [ "-verify", "-in", "test2.cms", "-inform", "DER",
+        "-CAfile", catfile($smdir, "smroot.pem"), "-out", "smtst.txt" ]
+    ],
+);
+
+my @incorrect_attribute_cms_test = (
+    "bad_signtime_attr.cms",
+    "no_ct_attr.cms",
+    "no_md_attr.cms",
+    "ct_multiple_attr.cms"
+);
+
 subtest "CMS => PKCS#7 compatibility tests\n" => sub {
     plan tests => scalar @smime_pkcs7_tests;
 
@@ -493,6 +514,52 @@ subtest "CMS <=> CMS consistency tests, modified key parameters\n" => sub {
     }
 };
 
+# Returns the number of matches of a Content Type Attribute in a binary file.
+sub contentType_matches {
+  # Read in a binary file
+  my ($in) = @_;
+  open (HEX_IN, "$in") or die("open failed for $in : $!");
+  binmode(HEX_IN);
+  local $/;
+  my $str = <HEX_IN>;
+
+  # Find ASN1 data for a Content Type Attribute (with a OID of PKCS7 data)
+  my @c = $str =~ /\x30\x18\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x01/gs;
+
+  close(HEX_IN);
+  return scalar(@c);
+}
+
+subtest "CMS Check the content type attribute is added for additional signers\n" => sub {
+    plan tests =>
+        (scalar @contenttype_cms_test);
+
+    foreach (@contenttype_cms_test) {
+      SKIP: {
+          my $skip_reason = check_availability($$_[0]);
+          skip $skip_reason, 1 if $skip_reason;
+
+          ok(run(app(["openssl", "cms", @{$$_[1]}]))
+             && run(app(["openssl", "cms", @{$$_[2]}]))
+             && contentType_matches("test2.cms") == 2
+             && run(app(["openssl", "cms", @{$$_[3]}])),
+             $$_[0]);
+        }
+    }
+};
+
+subtest "CMS Check that bad attributes fail when verifying signers\n" => sub {
+    plan tests =>
+        (scalar @incorrect_attribute_cms_test);
+
+    foreach my $name (@incorrect_attribute_cms_test) {
+        ok(!run(app(["openssl", "cms", "-verify", "-in",
+                     catfile($datadir, $name), "-inform", "DER", "-CAfile",
+                     catfile($smdir, "smroot.pem"), "-out", "smtst.txt" ])),
+            $name);
+    }
+};
+
 unlink "test.cms";
 unlink "test2.cms";
 unlink "smtst.txt";
diff --git a/test/recipes/80-test_cms_data/bad_signtime_attr.cms b/test/recipes/80-test_cms_data/bad_signtime_attr.cms
new file mode 100644 (file)
index 0000000..048a493
Binary files /dev/null and b/test/recipes/80-test_cms_data/bad_signtime_attr.cms differ
diff --git a/test/recipes/80-test_cms_data/ct_multiple_attr.cms b/test/recipes/80-test_cms_data/ct_multiple_attr.cms
new file mode 100644 (file)
index 0000000..974db6e
Binary files /dev/null and b/test/recipes/80-test_cms_data/ct_multiple_attr.cms differ
diff --git a/test/recipes/80-test_cms_data/no_ct_attr.cms b/test/recipes/80-test_cms_data/no_ct_attr.cms
new file mode 100644 (file)
index 0000000..64b688b
Binary files /dev/null and b/test/recipes/80-test_cms_data/no_ct_attr.cms differ
diff --git a/test/recipes/80-test_cms_data/no_md_attr.cms b/test/recipes/80-test_cms_data/no_md_attr.cms
new file mode 100644 (file)
index 0000000..d0a3afa
Binary files /dev/null and b/test/recipes/80-test_cms_data/no_md_attr.cms differ
index 633df47..adbcb4f 100644 (file)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -8,7 +8,7 @@
 
 
 use OpenSSL::Test::Utils;
-use OpenSSL::Test qw/:DEFAULT srctop_file/;
+use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir/;
 use File::Temp qw(tempfile);
 
 setup("test_sslapi");
@@ -20,8 +20,7 @@ plan tests => 1;
 
 (undef, my $tmpfilename) = tempfile();
 
-ok(run(test(["sslapitest", srctop_file("apps", "server.pem"),
-             srctop_file("apps", "server.pem"),
+ok(run(test(["sslapitest", srctop_dir("test", "certs"),
              srctop_file("test", "recipes", "90-test_sslapi_data",
                          "passwd.txt"), $tmpfilename])),
              "running sslapitest");
index 0bcd23d..93f3a1f 100644 (file)
@@ -1,6 +1,6 @@
 # Generated with generate_ssl_tests.pl
 
-num_tests = 51
+num_tests = 56
 
 test-0 = 0-ECDSA CipherString Selection
 test-1 = 1-ECDSA CipherString Selection
@@ -24,35 +24,40 @@ test-18 = 18-RSA-PSS Signature Algorithm Selection
 test-19 = 19-RSA-PSS Certificate Legacy Signature Algorithm Selection
 test-20 = 20-RSA-PSS Certificate Unified Signature Algorithm Selection
 test-21 = 21-Only RSA-PSS Certificate
-test-22 = 22-RSA-PSS Certificate, no PSS signature algorithms
-test-23 = 23-RSA key exchange with all RSA certificate types
-test-24 = 24-RSA key exchange with only RSA-PSS certificate
-test-25 = 25-Suite B P-256 Hash Algorithm Selection
-test-26 = 26-Suite B P-384 Hash Algorithm Selection
-test-27 = 27-TLS 1.2 Ed25519 Client Auth
-test-28 = 28-TLS 1.2 Ed448 Client Auth
-test-29 = 29-Only RSA-PSS Certificate, TLS v1.1
-test-30 = 30-TLS 1.3 ECDSA Signature Algorithm Selection
-test-31 = 31-TLS 1.3 ECDSA Signature Algorithm Selection compressed point
-test-32 = 32-TLS 1.3 ECDSA Signature Algorithm Selection SHA1
-test-33 = 33-TLS 1.3 ECDSA Signature Algorithm Selection with PSS
-test-34 = 34-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS
-test-35 = 35-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate
-test-36 = 36-TLS 1.3 RSA Signature Algorithm Selection, no PSS
-test-37 = 37-TLS 1.3 RSA-PSS Signature Algorithm Selection
-test-38 = 38-TLS 1.3 Ed25519 Signature Algorithm Selection
-test-39 = 39-TLS 1.3 Ed448 Signature Algorithm Selection
-test-40 = 40-TLS 1.3 Ed25519 CipherString and Groups Selection
-test-41 = 41-TLS 1.3 Ed448 CipherString and Groups Selection
-test-42 = 42-TLS 1.3 RSA Client Auth Signature Algorithm Selection
-test-43 = 43-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names
-test-44 = 44-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection
-test-45 = 45-TLS 1.3 Ed25519 Client Auth
-test-46 = 46-TLS 1.3 Ed448 Client Auth
-test-47 = 47-TLS 1.3 ECDSA with brainpool
-test-48 = 48-TLS 1.2 DSA Certificate Test
-test-49 = 49-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms
-test-50 = 50-TLS 1.3 DSA Certificate Test
+test-22 = 22-Only RSA-PSS Certificate Valid Signature Algorithms
+test-23 = 23-RSA-PSS Certificate, no PSS signature algorithms
+test-24 = 24-Only RSA-PSS Restricted Certificate
+test-25 = 25-RSA-PSS Restricted Certificate Valid Signature Algorithms
+test-26 = 26-RSA-PSS Restricted Cert client prefers invalid Signature Algorithm
+test-27 = 27-RSA-PSS Restricted Certificate Invalid Signature Algorithms
+test-28 = 28-RSA key exchange with all RSA certificate types
+test-29 = 29-RSA key exchange with only RSA-PSS certificate
+test-30 = 30-Suite B P-256 Hash Algorithm Selection
+test-31 = 31-Suite B P-384 Hash Algorithm Selection
+test-32 = 32-TLS 1.2 Ed25519 Client Auth
+test-33 = 33-TLS 1.2 Ed448 Client Auth
+test-34 = 34-Only RSA-PSS Certificate, TLS v1.1
+test-35 = 35-TLS 1.3 ECDSA Signature Algorithm Selection
+test-36 = 36-TLS 1.3 ECDSA Signature Algorithm Selection compressed point
+test-37 = 37-TLS 1.3 ECDSA Signature Algorithm Selection SHA1
+test-38 = 38-TLS 1.3 ECDSA Signature Algorithm Selection with PSS
+test-39 = 39-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS
+test-40 = 40-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate
+test-41 = 41-TLS 1.3 RSA Signature Algorithm Selection, no PSS
+test-42 = 42-TLS 1.3 RSA-PSS Signature Algorithm Selection
+test-43 = 43-TLS 1.3 Ed25519 Signature Algorithm Selection
+test-44 = 44-TLS 1.3 Ed448 Signature Algorithm Selection
+test-45 = 45-TLS 1.3 Ed25519 CipherString and Groups Selection
+test-46 = 46-TLS 1.3 Ed448 CipherString and Groups Selection
+test-47 = 47-TLS 1.3 RSA Client Auth Signature Algorithm Selection
+test-48 = 48-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names
+test-49 = 49-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection
+test-50 = 50-TLS 1.3 Ed25519 Client Auth
+test-51 = 51-TLS 1.3 Ed448 Client Auth
+test-52 = 52-TLS 1.3 ECDSA with brainpool
+test-53 = 53-TLS 1.2 DSA Certificate Test
+test-54 = 54-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms
+test-55 = 55-TLS 1.3 DSA Certificate Test
 # ===========================================================
 
 [0-ECDSA CipherString Selection]
@@ -775,89 +780,220 @@ ExpectedServerSignType = RSA-PSS
 
 # ===========================================================
 
-[22-RSA-PSS Certificate, no PSS signature algorithms]
-ssl_conf = 22-RSA-PSS Certificate, no PSS signature algorithms-ssl
+[22-Only RSA-PSS Certificate Valid Signature Algorithms]
+ssl_conf = 22-Only RSA-PSS Certificate Valid Signature Algorithms-ssl
 
-[22-RSA-PSS Certificate, no PSS signature algorithms-ssl]
-server = 22-RSA-PSS Certificate, no PSS signature algorithms-server
-client = 22-RSA-PSS Certificate, no PSS signature algorithms-client
+[22-Only RSA-PSS Certificate Valid Signature Algorithms-ssl]
+server = 22-Only RSA-PSS Certificate Valid Signature Algorithms-server
+client = 22-Only RSA-PSS Certificate Valid Signature Algorithms-client
 
-[22-RSA-PSS Certificate, no PSS signature algorithms-server]
+[22-Only RSA-PSS Certificate Valid Signature Algorithms-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-cert.pem
 CipherString = DEFAULT
 PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-key.pem
 
-[22-RSA-PSS Certificate, no PSS signature algorithms-client]
+[22-Only RSA-PSS Certificate Valid Signature Algorithms-client]
 CipherString = DEFAULT
-SignatureAlgorithms = RSA+SHA256
+SignatureAlgorithms = rsa_pss_pss_sha512
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
 [test-22]
+ExpectedResult = Success
+ExpectedServerCertType = RSA-PSS
+ExpectedServerSignHash = SHA512
+ExpectedServerSignType = RSA-PSS
+
+
+# ===========================================================
+
+[23-RSA-PSS Certificate, no PSS signature algorithms]
+ssl_conf = 23-RSA-PSS Certificate, no PSS signature algorithms-ssl
+
+[23-RSA-PSS Certificate, no PSS signature algorithms-ssl]
+server = 23-RSA-PSS Certificate, no PSS signature algorithms-server
+client = 23-RSA-PSS Certificate, no PSS signature algorithms-client
+
+[23-RSA-PSS Certificate, no PSS signature algorithms-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-cert.pem
+CipherString = DEFAULT
+PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-key.pem
+
+[23-RSA-PSS Certificate, no PSS signature algorithms-client]
+CipherString = DEFAULT
+SignatureAlgorithms = RSA+SHA256
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-23]
+ExpectedResult = ServerFail
+
+
+# ===========================================================
+
+[24-Only RSA-PSS Restricted Certificate]
+ssl_conf = 24-Only RSA-PSS Restricted Certificate-ssl
+
+[24-Only RSA-PSS Restricted Certificate-ssl]
+server = 24-Only RSA-PSS Restricted Certificate-server
+client = 24-Only RSA-PSS Restricted Certificate-client
+
+[24-Only RSA-PSS Restricted Certificate-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-restrict-cert.pem
+CipherString = DEFAULT
+PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-restrict-key.pem
+
+[24-Only RSA-PSS Restricted Certificate-client]
+CipherString = DEFAULT
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-24]
+ExpectedResult = Success
+ExpectedServerCertType = RSA-PSS
+ExpectedServerSignHash = SHA256
+ExpectedServerSignType = RSA-PSS
+
+
+# ===========================================================
+
+[25-RSA-PSS Restricted Certificate Valid Signature Algorithms]
+ssl_conf = 25-RSA-PSS Restricted Certificate Valid Signature Algorithms-ssl
+
+[25-RSA-PSS Restricted Certificate Valid Signature Algorithms-ssl]
+server = 25-RSA-PSS Restricted Certificate Valid Signature Algorithms-server
+client = 25-RSA-PSS Restricted Certificate Valid Signature Algorithms-client
+
+[25-RSA-PSS Restricted Certificate Valid Signature Algorithms-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-restrict-cert.pem
+CipherString = DEFAULT
+PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-restrict-key.pem
+
+[25-RSA-PSS Restricted Certificate Valid Signature Algorithms-client]
+CipherString = DEFAULT
+SignatureAlgorithms = rsa_pss_pss_sha256:rsa_pss_pss_sha512
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-25]
+ExpectedResult = Success
+ExpectedServerCertType = RSA-PSS
+ExpectedServerSignHash = SHA256
+ExpectedServerSignType = RSA-PSS
+
+
+# ===========================================================
+
+[26-RSA-PSS Restricted Cert client prefers invalid Signature Algorithm]
+ssl_conf = 26-RSA-PSS Restricted Cert client prefers invalid Signature Algorithm-ssl
+
+[26-RSA-PSS Restricted Cert client prefers invalid Signature Algorithm-ssl]
+server = 26-RSA-PSS Restricted Cert client prefers invalid Signature Algorithm-server
+client = 26-RSA-PSS Restricted Cert client prefers invalid Signature Algorithm-client
+
+[26-RSA-PSS Restricted Cert client prefers invalid Signature Algorithm-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-restrict-cert.pem
+CipherString = DEFAULT
+PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-restrict-key.pem
+
+[26-RSA-PSS Restricted Cert client prefers invalid Signature Algorithm-client]
+CipherString = DEFAULT
+SignatureAlgorithms = rsa_pss_pss_sha512:rsa_pss_pss_sha256
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-26]
+ExpectedResult = Success
+ExpectedServerCertType = RSA-PSS
+ExpectedServerSignHash = SHA256
+ExpectedServerSignType = RSA-PSS
+
+
+# ===========================================================
+
+[27-RSA-PSS Restricted Certificate Invalid Signature Algorithms]
+ssl_conf = 27-RSA-PSS Restricted Certificate Invalid Signature Algorithms-ssl
+
+[27-RSA-PSS Restricted Certificate Invalid Signature Algorithms-ssl]
+server = 27-RSA-PSS Restricted Certificate Invalid Signature Algorithms-server
+client = 27-RSA-PSS Restricted Certificate Invalid Signature Algorithms-client
+
+[27-RSA-PSS Restricted Certificate Invalid Signature Algorithms-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-restrict-cert.pem
+CipherString = DEFAULT
+PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-restrict-key.pem
+
+[27-RSA-PSS Restricted Certificate Invalid Signature Algorithms-client]
+CipherString = DEFAULT
+SignatureAlgorithms = rsa_pss_pss_sha512
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-27]
 ExpectedResult = ServerFail
 
 
 # ===========================================================
 
-[23-RSA key exchange with all RSA certificate types]
-ssl_conf = 23-RSA key exchange with all RSA certificate types-ssl
+[28-RSA key exchange with all RSA certificate types]
+ssl_conf = 28-RSA key exchange with all RSA certificate types-ssl
 
-[23-RSA key exchange with all RSA certificate types-ssl]
-server = 23-RSA key exchange with all RSA certificate types-server
-client = 23-RSA key exchange with all RSA certificate types-client
+[28-RSA key exchange with all RSA certificate types-ssl]
+server = 28-RSA key exchange with all RSA certificate types-server
+client = 28-RSA key exchange with all RSA certificate types-client
 
-[23-RSA key exchange with all RSA certificate types-server]
+[28-RSA key exchange with all RSA certificate types-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 PSS.Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-cert.pem
 PSS.PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-key.pem
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[23-RSA key exchange with all RSA certificate types-client]
+[28-RSA key exchange with all RSA certificate types-client]
 CipherString = kRSA
 MaxProtocol = TLSv1.2
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-23]
+[test-28]
 ExpectedResult = Success
 ExpectedServerCertType = RSA
 
 
 # ===========================================================
 
-[24-RSA key exchange with only RSA-PSS certificate]
-ssl_conf = 24-RSA key exchange with only RSA-PSS certificate-ssl
+[29-RSA key exchange with only RSA-PSS certificate]
+ssl_conf = 29-RSA key exchange with only RSA-PSS certificate-ssl
 
-[24-RSA key exchange with only RSA-PSS certificate-ssl]
-server = 24-RSA key exchange with only RSA-PSS certificate-server
-client = 24-RSA key exchange with only RSA-PSS certificate-client
+[29-RSA key exchange with only RSA-PSS certificate-ssl]
+server = 29-RSA key exchange with only RSA-PSS certificate-server
+client = 29-RSA key exchange with only RSA-PSS certificate-client
 
-[24-RSA key exchange with only RSA-PSS certificate-server]
+[29-RSA key exchange with only RSA-PSS certificate-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-cert.pem
 CipherString = DEFAULT
 PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-key.pem
 
-[24-RSA key exchange with only RSA-PSS certificate-client]
+[29-RSA key exchange with only RSA-PSS certificate-client]
 CipherString = kRSA
 MaxProtocol = TLSv1.2
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-24]
+[test-29]
 ExpectedResult = ServerFail
 
 
 # ===========================================================
 
-[25-Suite B P-256 Hash Algorithm Selection]
-ssl_conf = 25-Suite B P-256 Hash Algorithm Selection-ssl
+[30-Suite B P-256 Hash Algorithm Selection]
+ssl_conf = 30-Suite B P-256 Hash Algorithm Selection-ssl
 
-[25-Suite B P-256 Hash Algorithm Selection-ssl]
-server = 25-Suite B P-256 Hash Algorithm Selection-server
-client = 25-Suite B P-256 Hash Algorithm Selection-client
+[30-Suite B P-256 Hash Algorithm Selection-ssl]
+server = 30-Suite B P-256 Hash Algorithm Selection-server
+client = 30-Suite B P-256 Hash Algorithm Selection-client
 
-[25-Suite B P-256 Hash Algorithm Selection-server]
+[30-Suite B P-256 Hash Algorithm Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = SUITEB128
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/p256-server-cert.pem
@@ -865,13 +1001,13 @@ ECDSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/p256-server-key.pem
 MaxProtocol = TLSv1.2
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[25-Suite B P-256 Hash Algorithm Selection-client]
+[30-Suite B P-256 Hash Algorithm Selection-client]
 CipherString = DEFAULT
 SignatureAlgorithms = ECDSA+SHA384:ECDSA+SHA256
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/p384-root.pem
 VerifyMode = Peer
 
-[test-25]
+[test-30]
 ExpectedResult = Success
 ExpectedServerCertType = P-256
 ExpectedServerSignHash = SHA256
@@ -880,14 +1016,14 @@ ExpectedServerSignType = EC
 
 # ===========================================================
 
-[26-Suite B P-384 Hash Algorithm Selection]
-ssl_conf = 26-Suite B P-384 Hash Algorithm Selection-ssl
+[31-Suite B P-384 Hash Algorithm Selection]
+ssl_conf = 31-Suite B P-384 Hash Algorithm Selection-ssl
 
-[26-Suite B P-384 Hash Algorithm Selection-ssl]
-server = 26-Suite B P-384 Hash Algorithm Selection-server
-client = 26-Suite B P-384 Hash Algorithm Selection-client
+[31-Suite B P-384 Hash Algorithm Selection-ssl]
+server = 31-Suite B P-384 Hash Algorithm Selection-server
+client = 31-Suite B P-384 Hash Algorithm Selection-client
 
-[26-Suite B P-384 Hash Algorithm Selection-server]
+[31-Suite B P-384 Hash Algorithm Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = SUITEB128
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/p384-server-cert.pem
@@ -895,13 +1031,13 @@ ECDSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/p384-server-key.pem
 MaxProtocol = TLSv1.2
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[26-Suite B P-384 Hash Algorithm Selection-client]
+[31-Suite B P-384 Hash Algorithm Selection-client]
 CipherString = DEFAULT
 SignatureAlgorithms = ECDSA+SHA256:ECDSA+SHA384
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/p384-root.pem
 VerifyMode = Peer
 
-[test-26]
+[test-31]
 ExpectedResult = Success
 ExpectedServerCertType = P-384
 ExpectedServerSignHash = SHA384
@@ -910,21 +1046,21 @@ ExpectedServerSignType = EC
 
 # ===========================================================
 
-[27-TLS 1.2 Ed25519 Client Auth]
-ssl_conf = 27-TLS 1.2 Ed25519 Client Auth-ssl
+[32-TLS 1.2 Ed25519 Client Auth]
+ssl_conf = 32-TLS 1.2 Ed25519 Client Auth-ssl
 
-[27-TLS 1.2 Ed25519 Client Auth-ssl]
-server = 27-TLS 1.2 Ed25519 Client Auth-server
-client = 27-TLS 1.2 Ed25519 Client Auth-client
+[32-TLS 1.2 Ed25519 Client Auth-ssl]
+server = 32-TLS 1.2 Ed25519 Client Auth-server
+client = 32-TLS 1.2 Ed25519 Client Auth-client
 
-[27-TLS 1.2 Ed25519 Client Auth-server]
+[32-TLS 1.2 Ed25519 Client Auth-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyMode = Require
 
-[27-TLS 1.2 Ed25519 Client Auth-client]
+[32-TLS 1.2 Ed25519 Client Auth-client]
 CipherString = DEFAULT
 Ed25519.Certificate = ${ENV::TEST_CERTS_DIR}/client-ed25519-cert.pem
 Ed25519.PrivateKey = ${ENV::TEST_CERTS_DIR}/client-ed25519-key.pem
@@ -933,7 +1069,7 @@ MinProtocol = TLSv1.2
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-27]
+[test-32]
 ExpectedClientCertType = Ed25519
 ExpectedClientSignType = Ed25519
 ExpectedResult = Success
@@ -941,21 +1077,21 @@ ExpectedResult = Success
 
 # ===========================================================
 
-[28-TLS 1.2 Ed448 Client Auth]
-ssl_conf = 28-TLS 1.2 Ed448 Client Auth-ssl
+[33-TLS 1.2 Ed448 Client Auth]
+ssl_conf = 33-TLS 1.2 Ed448 Client Auth-ssl
 
-[28-TLS 1.2 Ed448 Client Auth-ssl]
-server = 28-TLS 1.2 Ed448 Client Auth-server
-client = 28-TLS 1.2 Ed448 Client Auth-client
+[33-TLS 1.2 Ed448 Client Auth-ssl]
+server = 33-TLS 1.2 Ed448 Client Auth-server
+client = 33-TLS 1.2 Ed448 Client Auth-client
 
-[28-TLS 1.2 Ed448 Client Auth-server]
+[33-TLS 1.2 Ed448 Client Auth-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyMode = Require
 
-[28-TLS 1.2 Ed448 Client Auth-client]
+[33-TLS 1.2 Ed448 Client Auth-client]
 CipherString = DEFAULT
 Ed448.Certificate = ${ENV::TEST_CERTS_DIR}/client-ed448-cert.pem
 Ed448.PrivateKey = ${ENV::TEST_CERTS_DIR}/client-ed448-key.pem
@@ -964,7 +1100,7 @@ MinProtocol = TLSv1.2
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-28]
+[test-33]
 ExpectedClientCertType = Ed448
 ExpectedClientSignType = Ed448
 ExpectedResult = Success
@@ -972,38 +1108,38 @@ ExpectedResult = Success
 
 # ===========================================================
 
-[29-Only RSA-PSS Certificate, TLS v1.1]
-ssl_conf = 29-Only RSA-PSS Certificate, TLS v1.1-ssl
+[34-Only RSA-PSS Certificate, TLS v1.1]
+ssl_conf = 34-Only RSA-PSS Certificate, TLS v1.1-ssl
 
-[29-Only RSA-PSS Certificate, TLS v1.1-ssl]
-server = 29-Only RSA-PSS Certificate, TLS v1.1-server
-client = 29-Only RSA-PSS Certificate, TLS v1.1-client
+[34-Only RSA-PSS Certificate, TLS v1.1-ssl]
+server = 34-Only RSA-PSS Certificate, TLS v1.1-server
+client = 34-Only RSA-PSS Certificate, TLS v1.1-client
 
-[29-Only RSA-PSS Certificate, TLS v1.1-server]
+[34-Only RSA-PSS Certificate, TLS v1.1-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/server-pss-cert.pem
 CipherString = DEFAULT
 PrivateKey = ${ENV::TEST_CERTS_DIR}/server-pss-key.pem
 
-[29-Only RSA-PSS Certificate, TLS v1.1-client]
+[34-Only RSA-PSS Certificate, TLS v1.1-client]
 CipherString = DEFAULT
 MaxProtocol = TLSv1.1
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-29]
+[test-34]
 ExpectedResult = ServerFail
 
 
 # ===========================================================
 
-[30-TLS 1.3 ECDSA Signature Algorithm Selection]
-ssl_conf = 30-TLS 1.3 ECDSA Signature Algorithm Selection-ssl
+[35-TLS 1.3 ECDSA Signature Algorithm Selection]
+ssl_conf = 35-TLS 1.3 ECDSA Signature Algorithm Selection-ssl
 
-[30-TLS 1.3 ECDSA Signature Algorithm Selection-ssl]
-server = 30-TLS 1.3 ECDSA Signature Algorithm Selection-server
-client = 30-TLS 1.3 ECDSA Signature Algorithm Selection-client
+[35-TLS 1.3 ECDSA Signature Algorithm Selection-ssl]
+server = 35-TLS 1.3 ECDSA Signature Algorithm Selection-server
+client = 35-TLS 1.3 ECDSA Signature Algorithm Selection-client
 
-[30-TLS 1.3 ECDSA Signature Algorithm Selection-server]
+[35-TLS 1.3 ECDSA Signature Algorithm Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1016,13 +1152,13 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[30-TLS 1.3 ECDSA Signature Algorithm Selection-client]
+[35-TLS 1.3 ECDSA Signature Algorithm Selection-client]
 CipherString = DEFAULT
 SignatureAlgorithms = ECDSA+SHA256
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-30]
+[test-35]
 ExpectedResult = Success
 ExpectedServerCANames = empty
 ExpectedServerCertType = P-256
@@ -1032,14 +1168,14 @@ ExpectedServerSignType = EC
 
 # ===========================================================
 
-[31-TLS 1.3 ECDSA Signature Algorithm Selection compressed point]
-ssl_conf = 31-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-ssl
+[36-TLS 1.3 ECDSA Signature Algorithm Selection compressed point]
+ssl_conf = 36-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-ssl
 
-[31-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-ssl]
-server = 31-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-server
-client = 31-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-client
+[36-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-ssl]
+server = 36-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-server
+client = 36-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-client
 
-[31-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-server]
+[36-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-cecdsa-cert.pem
@@ -1048,13 +1184,13 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[31-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-client]
+[36-TLS 1.3 ECDSA Signature Algorithm Selection compressed point-client]
 CipherString = DEFAULT
 SignatureAlgorithms = ECDSA+SHA256
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-31]
+[test-36]
 ExpectedResult = Success
 ExpectedServerCANames = empty
 ExpectedServerCertType = P-256
@@ -1064,14 +1200,14 @@ ExpectedServerSignType = EC
 
 # ===========================================================
 
-[32-TLS 1.3 ECDSA Signature Algorithm Selection SHA1]
-ssl_conf = 32-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-ssl
+[37-TLS 1.3 ECDSA Signature Algorithm Selection SHA1]
+ssl_conf = 37-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-ssl
 
-[32-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-ssl]
-server = 32-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-server
-client = 32-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-client
+[37-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-ssl]
+server = 37-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-server
+client = 37-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-client
 
-[32-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-server]
+[37-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1084,26 +1220,26 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[32-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-client]
+[37-TLS 1.3 ECDSA Signature Algorithm Selection SHA1-client]
 CipherString = DEFAULT
 SignatureAlgorithms = ECDSA+SHA1
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-32]
+[test-37]
 ExpectedResult = ServerFail
 
 
 # ===========================================================
 
-[33-TLS 1.3 ECDSA Signature Algorithm Selection with PSS]
-ssl_conf = 33-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-ssl
+[38-TLS 1.3 ECDSA Signature Algorithm Selection with PSS]
+ssl_conf = 38-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-ssl
 
-[33-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-ssl]
-server = 33-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-server
-client = 33-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-client
+[38-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-ssl]
+server = 38-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-server
+client = 38-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-client
 
-[33-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-server]
+[38-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1116,14 +1252,14 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[33-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-client]
+[38-TLS 1.3 ECDSA Signature Algorithm Selection with PSS-client]
 CipherString = DEFAULT
 RequestCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 SignatureAlgorithms = ECDSA+SHA256:RSA-PSS+SHA256
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-33]
+[test-38]
 ExpectedResult = Success
 ExpectedServerCANames = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 ExpectedServerCertType = P-256
@@ -1133,14 +1269,14 @@ ExpectedServerSignType = EC
 
 # ===========================================================
 
-[34-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS]
-ssl_conf = 34-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-ssl
+[39-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS]
+ssl_conf = 39-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-ssl
 
-[34-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-ssl]
-server = 34-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-server
-client = 34-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-client
+[39-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-ssl]
+server = 39-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-server
+client = 39-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-client
 
-[34-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-server]
+[39-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1153,13 +1289,13 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[34-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-client]
+[39-TLS 1.3 RSA Signature Algorithm Selection SHA384 with PSS-client]
 CipherString = DEFAULT
 SignatureAlgorithms = ECDSA+SHA384:RSA-PSS+SHA384
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-34]
+[test-39]
 ExpectedResult = Success
 ExpectedServerCertType = RSA
 ExpectedServerSignHash = SHA384
@@ -1168,40 +1304,40 @@ ExpectedServerSignType = RSA-PSS
 
 # ===========================================================
 
-[35-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate]
-ssl_conf = 35-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-ssl
+[40-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate]
+ssl_conf = 40-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-ssl
 
-[35-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-ssl]
-server = 35-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-server
-client = 35-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-client
+[40-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-ssl]
+server = 40-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-server
+client = 40-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-client
 
-[35-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-server]
+[40-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[35-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-client]
+[40-TLS 1.3 ECDSA Signature Algorithm Selection, no ECDSA certificate-client]
 CipherString = DEFAULT
 SignatureAlgorithms = ECDSA+SHA256
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-35]
+[test-40]
 ExpectedResult = ServerFail
 
 
 # ===========================================================
 
-[36-TLS 1.3 RSA Signature Algorithm Selection, no PSS]
-ssl_conf = 36-TLS 1.3 RSA Signature Algorithm Selection, no PSS-ssl
+[41-TLS 1.3 RSA Signature Algorithm Selection, no PSS]
+ssl_conf = 41-TLS 1.3 RSA Signature Algorithm Selection, no PSS-ssl
 
-[36-TLS 1.3 RSA Signature Algorithm Selection, no PSS-ssl]
-server = 36-TLS 1.3 RSA Signature Algorithm Selection, no PSS-server
-client = 36-TLS 1.3 RSA Signature Algorithm Selection, no PSS-client
+[41-TLS 1.3 RSA Signature Algorithm Selection, no PSS-ssl]
+server = 41-TLS 1.3 RSA Signature Algorithm Selection, no PSS-server
+client = 41-TLS 1.3 RSA Signature Algorithm Selection, no PSS-client
 
-[36-TLS 1.3 RSA Signature Algorithm Selection, no PSS-server]
+[41-TLS 1.3 RSA Signature Algorithm Selection, no PSS-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1214,26 +1350,26 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[36-TLS 1.3 RSA Signature Algorithm Selection, no PSS-client]
+[41-TLS 1.3 RSA Signature Algorithm Selection, no PSS-client]
 CipherString = DEFAULT
 SignatureAlgorithms = RSA+SHA256
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-36]
+[test-41]
 ExpectedResult = ServerFail
 
 
 # ===========================================================
 
-[37-TLS 1.3 RSA-PSS Signature Algorithm Selection]
-ssl_conf = 37-TLS 1.3 RSA-PSS Signature Algorithm Selection-ssl
+[42-TLS 1.3 RSA-PSS Signature Algorithm Selection]
+ssl_conf = 42-TLS 1.3 RSA-PSS Signature Algorithm Selection-ssl
 
-[37-TLS 1.3 RSA-PSS Signature Algorithm Selection-ssl]
-server = 37-TLS 1.3 RSA-PSS Signature Algorithm Selection-server
-client = 37-TLS 1.3 RSA-PSS Signature Algorithm Selection-client
+[42-TLS 1.3 RSA-PSS Signature Algorithm Selection-ssl]
+server = 42-TLS 1.3 RSA-PSS Signature Algorithm Selection-server
+client = 42-TLS 1.3 RSA-PSS Signature Algorithm Selection-client
 
-[37-TLS 1.3 RSA-PSS Signature Algorithm Selection-server]
+[42-TLS 1.3 RSA-PSS Signature Algorithm Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1246,13 +1382,13 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[37-TLS 1.3 RSA-PSS Signature Algorithm Selection-client]
+[42-TLS 1.3 RSA-PSS Signature Algorithm Selection-client]
 CipherString = DEFAULT
 SignatureAlgorithms = RSA-PSS+SHA256
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-37]
+[test-42]
 ExpectedResult = Success
 ExpectedServerCertType = RSA
 ExpectedServerSignHash = SHA256
@@ -1261,14 +1397,14 @@ ExpectedServerSignType = RSA-PSS
 
 # ===========================================================
 
-[38-TLS 1.3 Ed25519 Signature Algorithm Selection]
-ssl_conf = 38-TLS 1.3 Ed25519 Signature Algorithm Selection-ssl
+[43-TLS 1.3 Ed25519 Signature Algorithm Selection]
+ssl_conf = 43-TLS 1.3 Ed25519 Signature Algorithm Selection-ssl
 
-[38-TLS 1.3 Ed25519 Signature Algorithm Selection-ssl]
-server = 38-TLS 1.3 Ed25519 Signature Algorithm Selection-server
-client = 38-TLS 1.3 Ed25519 Signature Algorithm Selection-client
+[43-TLS 1.3 Ed25519 Signature Algorithm Selection-ssl]
+server = 43-TLS 1.3 Ed25519 Signature Algorithm Selection-server
+client = 43-TLS 1.3 Ed25519 Signature Algorithm Selection-client
 
-[38-TLS 1.3 Ed25519 Signature Algorithm Selection-server]
+[43-TLS 1.3 Ed25519 Signature Algorithm Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1281,13 +1417,13 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[38-TLS 1.3 Ed25519 Signature Algorithm Selection-client]
+[43-TLS 1.3 Ed25519 Signature Algorithm Selection-client]
 CipherString = DEFAULT
 SignatureAlgorithms = ed25519
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-38]
+[test-43]
 ExpectedResult = Success
 ExpectedServerCertType = Ed25519
 ExpectedServerSignType = Ed25519
@@ -1295,14 +1431,14 @@ ExpectedServerSignType = Ed25519
 
 # ===========================================================
 
-[39-TLS 1.3 Ed448 Signature Algorithm Selection]
-ssl_conf = 39-TLS 1.3 Ed448 Signature Algorithm Selection-ssl
+[44-TLS 1.3 Ed448 Signature Algorithm Selection]
+ssl_conf = 44-TLS 1.3 Ed448 Signature Algorithm Selection-ssl
 
-[39-TLS 1.3 Ed448 Signature Algorithm Selection-ssl]
-server = 39-TLS 1.3 Ed448 Signature Algorithm Selection-server
-client = 39-TLS 1.3 Ed448 Signature Algorithm Selection-client
+[44-TLS 1.3 Ed448 Signature Algorithm Selection-ssl]
+server = 44-TLS 1.3 Ed448 Signature Algorithm Selection-server
+client = 44-TLS 1.3 Ed448 Signature Algorithm Selection-client
 
-[39-TLS 1.3 Ed448 Signature Algorithm Selection-server]
+[44-TLS 1.3 Ed448 Signature Algorithm Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1315,13 +1451,13 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[39-TLS 1.3 Ed448 Signature Algorithm Selection-client]
+[44-TLS 1.3 Ed448 Signature Algorithm Selection-client]
 CipherString = DEFAULT
 SignatureAlgorithms = ed448
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-39]
+[test-44]
 ExpectedResult = Success
 ExpectedServerCertType = Ed448
 ExpectedServerSignType = Ed448
@@ -1329,14 +1465,14 @@ ExpectedServerSignType = Ed448
 
 # ===========================================================
 
-[40-TLS 1.3 Ed25519 CipherString and Groups Selection]
-ssl_conf = 40-TLS 1.3 Ed25519 CipherString and Groups Selection-ssl
+[45-TLS 1.3 Ed25519 CipherString and Groups Selection]
+ssl_conf = 45-TLS 1.3 Ed25519 CipherString and Groups Selection-ssl
 
-[40-TLS 1.3 Ed25519 CipherString and Groups Selection-ssl]
-server = 40-TLS 1.3 Ed25519 CipherString and Groups Selection-server
-client = 40-TLS 1.3 Ed25519 CipherString and Groups Selection-client
+[45-TLS 1.3 Ed25519 CipherString and Groups Selection-ssl]
+server = 45-TLS 1.3 Ed25519 CipherString and Groups Selection-server
+client = 45-TLS 1.3 Ed25519 CipherString and Groups Selection-client
 
-[40-TLS 1.3 Ed25519 CipherString and Groups Selection-server]
+[45-TLS 1.3 Ed25519 CipherString and Groups Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1349,14 +1485,14 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[40-TLS 1.3 Ed25519 CipherString and Groups Selection-client]
+[45-TLS 1.3 Ed25519 CipherString and Groups Selection-client]
 CipherString = DEFAULT
 Groups = X25519
 SignatureAlgorithms = ECDSA+SHA256:ed25519
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-40]
+[test-45]
 ExpectedResult = Success
 ExpectedServerCertType = P-256
 ExpectedServerSignType = EC
@@ -1364,14 +1500,14 @@ ExpectedServerSignType = EC
 
 # ===========================================================
 
-[41-TLS 1.3 Ed448 CipherString and Groups Selection]
-ssl_conf = 41-TLS 1.3 Ed448 CipherString and Groups Selection-ssl
+[46-TLS 1.3 Ed448 CipherString and Groups Selection]
+ssl_conf = 46-TLS 1.3 Ed448 CipherString and Groups Selection-ssl
 
-[41-TLS 1.3 Ed448 CipherString and Groups Selection-ssl]
-server = 41-TLS 1.3 Ed448 CipherString and Groups Selection-server
-client = 41-TLS 1.3 Ed448 CipherString and Groups Selection-client
+[46-TLS 1.3 Ed448 CipherString and Groups Selection-ssl]
+server = 46-TLS 1.3 Ed448 CipherString and Groups Selection-server
+client = 46-TLS 1.3 Ed448 CipherString and Groups Selection-client
 
-[41-TLS 1.3 Ed448 CipherString and Groups Selection-server]
+[46-TLS 1.3 Ed448 CipherString and Groups Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
@@ -1384,14 +1520,14 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[41-TLS 1.3 Ed448 CipherString and Groups Selection-client]
+[46-TLS 1.3 Ed448 CipherString and Groups Selection-client]
 CipherString = DEFAULT
 Groups = X448
 SignatureAlgorithms = ECDSA+SHA256:ed448
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-41]
+[test-46]
 ExpectedResult = Success
 ExpectedServerCertType = P-256
 ExpectedServerSignType = EC
@@ -1399,14 +1535,14 @@ ExpectedServerSignType = EC
 
 # ===========================================================
 
-[42-TLS 1.3 RSA Client Auth Signature Algorithm Selection]
-ssl_conf = 42-TLS 1.3 RSA Client Auth Signature Algorithm Selection-ssl
+[47-TLS 1.3 RSA Client Auth Signature Algorithm Selection]
+ssl_conf = 47-TLS 1.3 RSA Client Auth Signature Algorithm Selection-ssl
 
-[42-TLS 1.3 RSA Client Auth Signature Algorithm Selection-ssl]
-server = 42-TLS 1.3 RSA Client Auth Signature Algorithm Selection-server
-client = 42-TLS 1.3 RSA Client Auth Signature Algorithm Selection-client
+[47-TLS 1.3 RSA Client Auth Signature Algorithm Selection-ssl]
+server = 47-TLS 1.3 RSA Client Auth Signature Algorithm Selection-server
+client = 47-TLS 1.3 RSA Client Auth Signature Algorithm Selection-client
 
-[42-TLS 1.3 RSA Client Auth Signature Algorithm Selection-server]
+[47-TLS 1.3 RSA Client Auth Signature Algorithm Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ClientSignatureAlgorithms = PSS+SHA256
@@ -1414,7 +1550,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyMode = Require
 
-[42-TLS 1.3 RSA Client Auth Signature Algorithm Selection-client]
+[47-TLS 1.3 RSA Client Auth Signature Algorithm Selection-client]
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/ee-ecdsa-client-chain.pem
 ECDSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-ecdsa-key.pem
@@ -1425,7 +1561,7 @@ RSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-42]
+[test-47]
 ExpectedClientCANames = empty
 ExpectedClientCertType = RSA
 ExpectedClientSignHash = SHA256
@@ -1435,14 +1571,14 @@ ExpectedResult = Success
 
 # ===========================================================
 
-[43-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names]
-ssl_conf = 43-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-ssl
+[48-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names]
+ssl_conf = 48-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-ssl
 
-[43-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-ssl]
-server = 43-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-server
-client = 43-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-client
+[48-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-ssl]
+server = 48-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-server
+client = 48-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-client
 
-[43-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-server]
+[48-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ClientSignatureAlgorithms = PSS+SHA256
@@ -1451,7 +1587,7 @@ RequestCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyMode = Require
 
-[43-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-client]
+[48-TLS 1.3 RSA Client Auth Signature Algorithm Selection non-empty CA Names-client]
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/ee-ecdsa-client-chain.pem
 ECDSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-ecdsa-key.pem
@@ -1462,7 +1598,7 @@ RSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-43]
+[test-48]
 ExpectedClientCANames = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 ExpectedClientCertType = RSA
 ExpectedClientSignHash = SHA256
@@ -1472,14 +1608,14 @@ ExpectedResult = Success
 
 # ===========================================================
 
-[44-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection]
-ssl_conf = 44-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-ssl
+[49-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection]
+ssl_conf = 49-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-ssl
 
-[44-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-ssl]
-server = 44-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-server
-client = 44-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-client
+[49-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-ssl]
+server = 49-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-server
+client = 49-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-client
 
-[44-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-server]
+[49-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ClientSignatureAlgorithms = ECDSA+SHA256
@@ -1487,7 +1623,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyMode = Require
 
-[44-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-client]
+[49-TLS 1.3 ECDSA Client Auth Signature Algorithm Selection-client]
 CipherString = DEFAULT
 ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/ee-ecdsa-client-chain.pem
 ECDSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-ecdsa-key.pem
@@ -1498,7 +1634,7 @@ RSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-44]
+[test-49]
 ExpectedClientCertType = P-256
 ExpectedClientSignHash = SHA256
 ExpectedClientSignType = EC
@@ -1507,21 +1643,21 @@ ExpectedResult = Success
 
 # ===========================================================
 
-[45-TLS 1.3 Ed25519 Client Auth]
-ssl_conf = 45-TLS 1.3 Ed25519 Client Auth-ssl
+[50-TLS 1.3 Ed25519 Client Auth]
+ssl_conf = 50-TLS 1.3 Ed25519 Client Auth-ssl
 
-[45-TLS 1.3 Ed25519 Client Auth-ssl]
-server = 45-TLS 1.3 Ed25519 Client Auth-server
-client = 45-TLS 1.3 Ed25519 Client Auth-client
+[50-TLS 1.3 Ed25519 Client Auth-ssl]
+server = 50-TLS 1.3 Ed25519 Client Auth-server
+client = 50-TLS 1.3 Ed25519 Client Auth-client
 
-[45-TLS 1.3 Ed25519 Client Auth-server]
+[50-TLS 1.3 Ed25519 Client Auth-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyMode = Require
 
-[45-TLS 1.3 Ed25519 Client Auth-client]
+[50-TLS 1.3 Ed25519 Client Auth-client]
 CipherString = DEFAULT
 EdDSA.Certificate = ${ENV::TEST_CERTS_DIR}/client-ed25519-cert.pem
 EdDSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/client-ed25519-key.pem
@@ -1530,7 +1666,7 @@ MinProtocol = TLSv1.3
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-45]
+[test-50]
 ExpectedClientCertType = Ed25519
 ExpectedClientSignType = Ed25519
 ExpectedResult = Success
@@ -1538,21 +1674,21 @@ ExpectedResult = Success
 
 # ===========================================================
 
-[46-TLS 1.3 Ed448 Client Auth]
-ssl_conf = 46-TLS 1.3 Ed448 Client Auth-ssl
+[51-TLS 1.3 Ed448 Client Auth]
+ssl_conf = 51-TLS 1.3 Ed448 Client Auth-ssl
 
-[46-TLS 1.3 Ed448 Client Auth-ssl]
-server = 46-TLS 1.3 Ed448 Client Auth-server
-client = 46-TLS 1.3 Ed448 Client Auth-client
+[51-TLS 1.3 Ed448 Client Auth-ssl]
+server = 51-TLS 1.3 Ed448 Client Auth-server
+client = 51-TLS 1.3 Ed448 Client Auth-client
 
-[46-TLS 1.3 Ed448 Client Auth-server]
+[51-TLS 1.3 Ed448 Client Auth-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyMode = Require
 
-[46-TLS 1.3 Ed448 Client Auth-client]
+[51-TLS 1.3 Ed448 Client Auth-client]
 CipherString = DEFAULT
 EdDSA.Certificate = ${ENV::TEST_CERTS_DIR}/client-ed448-cert.pem
 EdDSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/client-ed448-key.pem
@@ -1561,7 +1697,7 @@ MinProtocol = TLSv1.3
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-46]
+[test-51]
 ExpectedClientCertType = Ed448
 ExpectedClientSignType = Ed448
 ExpectedResult = Success
@@ -1569,20 +1705,20 @@ ExpectedResult = Success
 
 # ===========================================================
 
-[47-TLS 1.3 ECDSA with brainpool]
-ssl_conf = 47-TLS 1.3 ECDSA with brainpool-ssl
+[52-TLS 1.3 ECDSA with brainpool]
+ssl_conf = 52-TLS 1.3 ECDSA with brainpool-ssl
 
-[47-TLS 1.3 ECDSA with brainpool-ssl]
-server = 47-TLS 1.3 ECDSA with brainpool-server
-client = 47-TLS 1.3 ECDSA with brainpool-client
+[52-TLS 1.3 ECDSA with brainpool-ssl]
+server = 52-TLS 1.3 ECDSA with brainpool-server
+client = 52-TLS 1.3 ECDSA with brainpool-client
 
-[47-TLS 1.3 ECDSA with brainpool-server]
+[52-TLS 1.3 ECDSA with brainpool-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-brainpoolP256r1-cert.pem
 CipherString = DEFAULT
 Groups = brainpoolP256r1
 PrivateKey = ${ENV::TEST_CERTS_DIR}/server-ecdsa-brainpoolP256r1-key.pem
 
-[47-TLS 1.3 ECDSA with brainpool-client]
+[52-TLS 1.3 ECDSA with brainpool-client]
 CipherString = DEFAULT
 Groups = brainpoolP256r1
 MaxProtocol = TLSv1.3
@@ -1591,20 +1727,20 @@ RequestCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-47]
+[test-52]
 ExpectedResult = ServerFail
 
 
 # ===========================================================
 
-[48-TLS 1.2 DSA Certificate Test]
-ssl_conf = 48-TLS 1.2 DSA Certificate Test-ssl
+[53-TLS 1.2 DSA Certificate Test]
+ssl_conf = 53-TLS 1.2 DSA Certificate Test-ssl
 
-[48-TLS 1.2 DSA Certificate Test-ssl]
-server = 48-TLS 1.2 DSA Certificate Test-server
-client = 48-TLS 1.2 DSA Certificate Test-client
+[53-TLS 1.2 DSA Certificate Test-ssl]
+server = 53-TLS 1.2 DSA Certificate Test-server
+client = 53-TLS 1.2 DSA Certificate Test-client
 
-[48-TLS 1.2 DSA Certificate Test-server]
+[53-TLS 1.2 DSA Certificate Test-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = ALL
 DHParameters = ${ENV::TEST_CERTS_DIR}/dhp2048.pem
@@ -1614,26 +1750,26 @@ MaxProtocol = TLSv1.2
 MinProtocol = TLSv1.2
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[48-TLS 1.2 DSA Certificate Test-client]
+[53-TLS 1.2 DSA Certificate Test-client]
 CipherString = ALL
 SignatureAlgorithms = DSA+SHA256:DSA+SHA1
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-48]
+[test-53]
 ExpectedResult = Success
 
 
 # ===========================================================
 
-[49-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms]
-ssl_conf = 49-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-ssl
+[54-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms]
+ssl_conf = 54-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-ssl
 
-[49-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-ssl]
-server = 49-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-server
-client = 49-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-client
+[54-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-ssl]
+server = 54-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-server
+client = 54-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-client
 
-[49-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-server]
+[54-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
 ClientSignatureAlgorithms = ECDSA+SHA1:DSA+SHA256:RSA+SHA256
@@ -1641,25 +1777,25 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyMode = Request
 
-[49-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-client]
+[54-TLS 1.3 Client Auth No TLS 1.3 Signature Algorithms-client]
 CipherString = DEFAULT
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-49]
+[test-54]
 ExpectedResult = ServerFail
 
 
 # ===========================================================
 
-[50-TLS 1.3 DSA Certificate Test]
-ssl_conf = 50-TLS 1.3 DSA Certificate Test-ssl
+[55-TLS 1.3 DSA Certificate Test]
+ssl_conf = 55-TLS 1.3 DSA Certificate Test-ssl
 
-[50-TLS 1.3 DSA Certificate Test-ssl]
-server = 50-TLS 1.3 DSA Certificate Test-server
-client = 50-TLS 1.3 DSA Certificate Test-client
+[55-TLS 1.3 DSA Certificate Test-ssl]
+server = 55-TLS 1.3 DSA Certificate Test-server
+client = 55-TLS 1.3 DSA Certificate Test-client
 
-[50-TLS 1.3 DSA Certificate Test-server]
+[55-TLS 1.3 DSA Certificate Test-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = ALL
 DSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-dsa-cert.pem
@@ -1668,13 +1804,13 @@ MaxProtocol = TLSv1.3
 MinProtocol = TLSv1.3
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
-[50-TLS 1.3 DSA Certificate Test-client]
+[55-TLS 1.3 DSA Certificate Test-client]
 CipherString = ALL
 SignatureAlgorithms = DSA+SHA1:DSA+SHA256:ECDSA+SHA256
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
-[test-50]
+[test-55]
 ExpectedResult = ServerFail
 
 
index bdf53c6..5e9bfed 100644 (file)
@@ -36,6 +36,12 @@ my $server_pss_only = {
     "PrivateKey" => test_pem("server-pss-key.pem"),
 };
 
+my $server_pss_restrict_only = {
+    "Certificate" => test_pem("server-pss-restrict-cert.pem"),
+    "PrivateKey" => test_pem("server-pss-restrict-key.pem"),
+};
+
+
 my $server_rsa_all = {
     "PSS.Certificate" => test_pem("server-pss-cert.pem"),
     "PSS.PrivateKey" => test_pem("server-pss-key.pem"),
@@ -380,6 +386,19 @@ our @tests = (
         },
     },
     {
+        name => "Only RSA-PSS Certificate Valid Signature Algorithms",
+        server => $server_pss_only,
+        client => {
+            "SignatureAlgorithms" => "rsa_pss_pss_sha512",
+        },
+        test   => {
+            "ExpectedServerCertType" => "RSA-PSS",
+            "ExpectedServerSignHash" => "SHA512",
+            "ExpectedServerSignType" => "RSA-PSS",
+            "ExpectedResult" => "Success"
+        },
+    },
+    {
         name => "RSA-PSS Certificate, no PSS signature algorithms",
         server => $server_pss_only,
         client => {
@@ -390,6 +409,53 @@ our @tests = (
         },
     },
     {
+        name => "Only RSA-PSS Restricted Certificate",
+        server => $server_pss_restrict_only,
+        client => {},
+        test   => {
+            "ExpectedServerCertType" => "RSA-PSS",
+            "ExpectedServerSignHash" => "SHA256",
+            "ExpectedServerSignType" => "RSA-PSS",
+            "ExpectedResult" => "Success"
+        },
+    },
+    {
+        name => "RSA-PSS Restricted Certificate Valid Signature Algorithms",
+        server => $server_pss_restrict_only,
+        client => {
+            "SignatureAlgorithms" => "rsa_pss_pss_sha256:rsa_pss_pss_sha512",
+        },
+        test   => {
+            "ExpectedServerCertType" => "RSA-PSS",
+            "ExpectedServerSignHash" => "SHA256",
+            "ExpectedServerSignType" => "RSA-PSS",
+            "ExpectedResult" => "Success"
+        },
+    },
+    {
+        name => "RSA-PSS Restricted Cert client prefers invalid Signature Algorithm",
+        server => $server_pss_restrict_only,
+        client => {
+            "SignatureAlgorithms" => "rsa_pss_pss_sha512:rsa_pss_pss_sha256",
+        },
+        test   => {
+            "ExpectedServerCertType" => "RSA-PSS",
+            "ExpectedServerSignHash" => "SHA256",
+            "ExpectedServerSignType" => "RSA-PSS",
+            "ExpectedResult" => "Success"
+        },
+    },
+    {
+        name => "RSA-PSS Restricted Certificate Invalid Signature Algorithms",
+        server => $server_pss_restrict_only,
+        client => {
+            "SignatureAlgorithms" => "rsa_pss_pss_sha512",
+        },
+        test   => {
+            "ExpectedResult" => "ServerFail"
+        },
+    },
+    {
         name => "RSA key exchange with all RSA certificate types",
         server => $server_rsa_all,
         client => {
index 2261fe4..7a14226 100644 (file)
@@ -42,6 +42,7 @@ static int find_session_cb_cnt = 0;
 static SSL_SESSION *create_a_psk(SSL *ssl);
 #endif
 
+static char *certsdir = NULL;
 static char *cert = NULL;
 static char *privkey = NULL;
 static char *srpvfile = NULL;
@@ -3289,6 +3290,142 @@ static int test_ciphersuite_change(void)
 }
 
 /*
+ * Test TLSv1.3 Cipher Suite
+ * Test 0 = Set TLS1.3 cipher on context
+ * Test 1 = Set TLS1.3 cipher on SSL
+ * Test 2 = Set TLS1.3 and TLS1.2 cipher on context
+ * Test 3 = Set TLS1.3 and TLS1.2 cipher on SSL
+ */
+static int test_tls13_ciphersuite(int idx)
+{
+    SSL_CTX *sctx = NULL, *cctx = NULL;
+    SSL *serverssl = NULL, *clientssl = NULL;
+    static const char *t13_ciphers[] = {
+        TLS1_3_RFC_AES_128_GCM_SHA256,
+        TLS1_3_RFC_AES_256_GCM_SHA384,
+        TLS1_3_RFC_AES_128_CCM_SHA256,
+# if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+        TLS1_3_RFC_CHACHA20_POLY1305_SHA256,
+        TLS1_3_RFC_AES_256_GCM_SHA384 ":" TLS1_3_RFC_CHACHA20_POLY1305_SHA256,
+# endif
+        TLS1_3_RFC_AES_128_CCM_8_SHA256 ":" TLS1_3_RFC_AES_128_CCM_SHA256
+    };
+    const char *t13_cipher = NULL;
+    const char *t12_cipher = NULL;
+    const char *negotiated_scipher;
+    const char *negotiated_ccipher;
+    int set_at_ctx = 0;
+    int set_at_ssl = 0;
+    int testresult = 0;
+    int max_ver;
+    size_t i;
+
+    switch (idx) {
+        case 0:
+            set_at_ctx = 1;
+            break;
+        case 1:
+            set_at_ssl = 1;
+            break;
+        case 2:
+            set_at_ctx = 1;
+            t12_cipher = TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
+            break;
+        case 3:
+            set_at_ssl = 1;
+            t12_cipher = TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
+            break;
+    }
+
+    for (max_ver = TLS1_2_VERSION; max_ver <= TLS1_3_VERSION; max_ver++) {
+# ifdef OPENSSL_NO_TLS1_2
+        if (max_ver == TLS1_2_VERSION)
+            continue;
+# endif
+        for (i = 0; i < OSSL_NELEM(t13_ciphers); i++) {
+            t13_cipher = t13_ciphers[i];
+            if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+                                               TLS_client_method(),
+                                               TLS1_VERSION, max_ver,
+                                               &sctx, &cctx, cert, privkey)))
+                goto end;
+
+            if (set_at_ctx) {
+                if (!TEST_true(SSL_CTX_set_ciphersuites(sctx, t13_cipher))
+                    || !TEST_true(SSL_CTX_set_ciphersuites(cctx, t13_cipher)))
+                    goto end;
+                if (t12_cipher != NULL) {
+                    if (!TEST_true(SSL_CTX_set_cipher_list(sctx, t12_cipher))
+                        || !TEST_true(SSL_CTX_set_cipher_list(cctx,
+                                                              t12_cipher)))
+                        goto end;
+                }
+            }
+
+            if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
+                                              &clientssl, NULL, NULL)))
+                goto end;
+
+            if (set_at_ssl) {
+                if (!TEST_true(SSL_set_ciphersuites(serverssl, t13_cipher))
+                    || !TEST_true(SSL_set_ciphersuites(clientssl, t13_cipher)))
+                    goto end;
+                if (t12_cipher != NULL) {
+                    if (!TEST_true(SSL_set_cipher_list(serverssl, t12_cipher))
+                        || !TEST_true(SSL_set_cipher_list(clientssl,
+                                                          t12_cipher)))
+                        goto end;
+                }
+            }
+
+            if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+                                                 SSL_ERROR_NONE)))
+                goto end;
+
+            negotiated_scipher = SSL_CIPHER_get_name(SSL_get_current_cipher(
+                                                                 serverssl));
+            negotiated_ccipher = SSL_CIPHER_get_name(SSL_get_current_cipher(
+                                                                 clientssl));
+            if (!TEST_str_eq(negotiated_scipher, negotiated_ccipher))
+                goto end;
+
+            /*
+             * TEST_strn_eq is used below because t13_cipher can contain
+             * multiple ciphersuites
+             */
+            if (max_ver == TLS1_3_VERSION
+                && !TEST_strn_eq(t13_cipher, negotiated_scipher,
+                                 strlen(negotiated_scipher)))
+                goto end;
+
+# ifndef OPENSSL_NO_TLS1_2
+            /* Below validation is not done when t12_cipher is NULL */
+            if (max_ver == TLS1_2_VERSION && t12_cipher != NULL
+                && !TEST_str_eq(t12_cipher, negotiated_scipher))
+                goto end;
+# endif
+
+            SSL_free(serverssl);
+            serverssl = NULL;
+            SSL_free(clientssl);
+            clientssl = NULL;
+            SSL_CTX_free(sctx);
+            sctx = NULL;
+            SSL_CTX_free(cctx);
+            cctx = NULL;
+        }
+    }
+
+    testresult = 1;
+ end:
+    SSL_free(serverssl);
+    SSL_free(clientssl);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+    return testresult;
+}
+
+/*
  * Test TLSv1.3 PSKs
  * Test 0 = Test new style callbacks
  * Test 1 = Test both new and old style callbacks
@@ -4290,7 +4427,95 @@ static int test_key_update(void)
                 || !TEST_int_eq(SSL_read(serverssl, buf, sizeof(buf)),
                                          strlen(mess)))
             goto end;
+
+        if (!TEST_int_eq(SSL_write(serverssl, mess, strlen(mess)), strlen(mess))
+                || !TEST_int_eq(SSL_read(clientssl, buf, sizeof(buf)),
+                                         strlen(mess)))
+            goto end;
+    }
+
+    testresult = 1;
+
+ end:
+    SSL_free(serverssl);
+    SSL_free(clientssl);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+
+    return testresult;
+}
+
+/*
+ * Test we can handle a KeyUpdate (update requested) message while write data
+ * is pending.
+ * Test 0: Client sends KeyUpdate while Server is writing
+ * Test 1: Server sends KeyUpdate while Client is writing
+ */
+static int test_key_update_in_write(int tst)
+{
+    SSL_CTX *cctx = NULL, *sctx = NULL;
+    SSL *clientssl = NULL, *serverssl = NULL;
+    int testresult = 0;
+    char buf[20];
+    static char *mess = "A test message";
+    BIO *bretry = BIO_new(bio_s_always_retry());
+    BIO *tmp = NULL;
+    SSL *peerupdate = NULL, *peerwrite = NULL;
+
+    if (!TEST_ptr(bretry)
+            || !TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+                                              TLS_client_method(),
+                                              TLS1_3_VERSION,
+                                              0,
+                                              &sctx, &cctx, cert, privkey))
+            || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+                                             NULL, NULL))
+            || !TEST_true(create_ssl_connection(serverssl, clientssl,
+                                                SSL_ERROR_NONE)))
+        goto end;
+
+    peerupdate = tst == 0 ? clientssl : serverssl;
+    peerwrite = tst == 0 ? serverssl : clientssl;
+
+    if (!TEST_true(SSL_key_update(peerupdate, SSL_KEY_UPDATE_REQUESTED))
+            || !TEST_true(SSL_do_handshake(peerupdate)))
+        goto end;
+
+    /* Swap the writing endpoint's write BIO to force a retry */
+    tmp = SSL_get_wbio(peerwrite);
+    if (!TEST_ptr(tmp) || !TEST_true(BIO_up_ref(tmp))) {
+        tmp = NULL;
+        goto end;
     }
+    SSL_set0_wbio(peerwrite, bretry);
+    bretry = NULL;
+
+    /* Write data that we know will fail with SSL_ERROR_WANT_WRITE */
+    if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), -1)
+            || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_WRITE))
+        goto end;
+
+    /* Reinstate the original writing endpoint's write BIO */
+    SSL_set0_wbio(peerwrite, tmp);
+    tmp = NULL;
+
+    /* Now read some data - we will read the key update */
+    if (!TEST_int_eq(SSL_read(peerwrite, buf, sizeof(buf)), -1)
+            || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_READ))
+        goto end;
+
+    /*
+     * Complete the write we started previously and read it from the other
+     * endpoint
+     */
+    if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), strlen(mess))
+            || !TEST_int_eq(SSL_read(peerupdate, buf, sizeof(buf)), strlen(mess)))
+        goto end;
+
+    /* Write more data to ensure we send the KeyUpdate message back */
+    if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), strlen(mess))
+            || !TEST_int_eq(SSL_read(peerupdate, buf, sizeof(buf)), strlen(mess)))
+        goto end;
 
     testresult = 1;
 
@@ -4299,6 +4524,8 @@ static int test_key_update(void)
     SSL_free(clientssl);
     SSL_CTX_free(sctx);
     SSL_CTX_free(cctx);
+    BIO_free(bretry);
+    BIO_free(tmp);
 
     return testresult;
 }
@@ -5572,6 +5799,12 @@ static int cert_cb_cnt;
 static int cert_cb(SSL *s, void *arg)
 {
     SSL_CTX *ctx = (SSL_CTX *)arg;
+    BIO *in = NULL;
+    EVP_PKEY *pkey = NULL;
+    X509 *x509 = NULL, *rootx = NULL;
+    STACK_OF(X509) *chain = NULL;
+    char *rootfile = NULL, *ecdsacert = NULL, *ecdsakey = NULL;
+    int ret = 0;
 
     if (cert_cb_cnt == 0) {
         /* Suspend the handshake */
@@ -5592,10 +5825,60 @@ static int cert_cb(SSL *s, void *arg)
             return 0;
         cert_cb_cnt++;
         return 1;
+    } else if (cert_cb_cnt == 3) {
+        int rv;
+
+        rootfile = test_mk_file_path(certsdir, "rootcert.pem");
+        ecdsacert = test_mk_file_path(certsdir, "server-ecdsa-cert.pem");
+        ecdsakey = test_mk_file_path(certsdir, "server-ecdsa-key.pem");
+        if (!TEST_ptr(rootfile) || !TEST_ptr(ecdsacert) || !TEST_ptr(ecdsakey))
+            goto out;
+        chain = sk_X509_new_null();
+        if (!TEST_ptr(chain))
+            goto out;
+        if (!TEST_ptr(in = BIO_new(BIO_s_file()))
+                || !TEST_int_ge(BIO_read_filename(in, rootfile), 0)
+                || !TEST_ptr(rootx = PEM_read_bio_X509(in, NULL, NULL, NULL))
+                || !TEST_true(sk_X509_push(chain, rootx)))
+            goto out;
+        rootx = NULL;
+        BIO_free(in);
+        if (!TEST_ptr(in = BIO_new(BIO_s_file()))
+                || !TEST_int_ge(BIO_read_filename(in, ecdsacert), 0)
+                || !TEST_ptr(x509 = PEM_read_bio_X509(in, NULL, NULL, NULL)))
+            goto out;
+        BIO_free(in);
+        if (!TEST_ptr(in = BIO_new(BIO_s_file()))
+                || !TEST_int_ge(BIO_read_filename(in, ecdsakey), 0)
+                || !TEST_ptr(pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL)))
+            goto out;
+        rv = SSL_check_chain(s, x509, pkey, chain);
+        /*
+         * If the cert doesn't show as valid here (e.g., because we don't
+         * have any shared sigalgs), then we will not set it, and there will
+         * be no certificate at all on the SSL or SSL_CTX.  This, in turn,
+         * will cause tls_choose_sigalgs() to fail the connection.
+         */
+        if ((rv & (CERT_PKEY_VALID | CERT_PKEY_CA_SIGNATURE))
+                == (CERT_PKEY_VALID | CERT_PKEY_CA_SIGNATURE)) {
+            if (!SSL_use_cert_and_key(s, x509, pkey, NULL, 1))
+                goto out;
+        }
+
+        ret = 1;
     }
 
     /* Abort the handshake */
-    return 0;
+ out:
+    OPENSSL_free(ecdsacert);
+    OPENSSL_free(ecdsakey);
+    OPENSSL_free(rootfile);
+    BIO_free(in);
+    EVP_PKEY_free(pkey);
+    X509_free(x509);
+    X509_free(rootx);
+    sk_X509_pop_free(chain, X509_free);
+    return ret;
 }
 
 /*
@@ -5603,6 +5886,10 @@ static int cert_cb(SSL *s, void *arg)
  * Test 0: Callback fails
  * Test 1: Success - no SSL_set_SSL_CTX() in the callback
  * Test 2: Success - SSL_set_SSL_CTX() in the callback
+ * Test 3: Success - Call SSL_check_chain from the callback
+ * Test 4: Failure - SSL_check_chain fails from callback due to bad cert in the
+ *                   chain
+ * Test 5: Failure - SSL_check_chain fails from callback due to bad ee cert
  */
 static int test_cert_cb_int(int prot, int tst)
 {
@@ -5610,6 +5897,12 @@ static int test_cert_cb_int(int prot, int tst)
     SSL *clientssl = NULL, *serverssl = NULL;
     int testresult = 0, ret;
 
+#ifdef OPENSSL_NO_EC
+    /* We use an EC cert in these tests, so we skip in a no-ec build */
+    if (tst >= 3)
+        return 1;
+#endif
+
     if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
                                        TLS_client_method(),
                                        TLS1_VERSION,
@@ -5619,8 +5912,11 @@ static int test_cert_cb_int(int prot, int tst)
 
     if (tst == 0)
         cert_cb_cnt = -1;
+    else if (tst >= 3)
+        cert_cb_cnt = 3;
     else
         cert_cb_cnt = 0;
+
     if (tst == 2)
         snictx = SSL_CTX_new(TLS_server_method());
     SSL_CTX_set_cert_cb(sctx, cert_cb, snictx);
@@ -5629,9 +5925,28 @@ static int test_cert_cb_int(int prot, int tst)
                                       NULL, NULL)))
         goto end;
 
+    if (tst == 4) {
+        /*
+         * We cause SSL_check_chain() to fail by specifying sig_algs that
+         * the chain doesn't meet (the root uses an RSA cert)
+         */
+        if (!TEST_true(SSL_set1_sigalgs_list(clientssl,
+                                             "ecdsa_secp256r1_sha256")))
+            goto end;
+    } else if (tst == 5) {
+        /*
+         * We cause SSL_check_chain() to fail by specifying sig_algs that
+         * the ee cert doesn't meet (the ee uses an ECDSA cert)
+         */
+        if (!TEST_true(SSL_set1_sigalgs_list(clientssl,
+                           "rsa_pss_rsae_sha256:rsa_pkcs1_sha256")))
+            goto end;
+    }
+
     ret = create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE);
-    if (!TEST_true(tst == 0 ? !ret : ret)
-            || (tst > 0 && !TEST_int_eq(cert_cb_cnt, 2))) {
+    if (!TEST_true(tst == 0 || tst == 4 || tst == 5 ? !ret : ret)
+            || (tst > 0
+                && !TEST_int_eq((cert_cb_cnt - 2) * (cert_cb_cnt - 3), 0))) {
         goto end;
     }
 
@@ -5892,10 +6207,9 @@ static int test_ca_names(int tst)
 
 int setup_tests(void)
 {
-    if (!TEST_ptr(cert = test_get_argument(0))
-            || !TEST_ptr(privkey = test_get_argument(1))
-            || !TEST_ptr(srpvfile = test_get_argument(2))
-            || !TEST_ptr(tmpfilename = test_get_argument(3)))
+    if (!TEST_ptr(certsdir = test_get_argument(0))
+            || !TEST_ptr(srpvfile = test_get_argument(1))
+            || !TEST_ptr(tmpfilename = test_get_argument(2)))
         return 0;
 
     if (getenv("OPENSSL_TEST_GETCOUNTS") != NULL) {
@@ -5914,6 +6228,16 @@ int setup_tests(void)
 #endif
     }
 
+    cert = test_mk_file_path(certsdir, "servercert.pem");
+    if (cert == NULL)
+        return 0;
+
+    privkey = test_mk_file_path(certsdir, "serverkey.pem");
+    if (privkey == NULL) {
+        OPENSSL_free(cert);
+        return 0;
+    }
+
     ADD_TEST(test_large_message_tls);
     ADD_TEST(test_large_message_tls_read_ahead);
 #ifndef OPENSSL_NO_DTLS
@@ -5966,6 +6290,7 @@ int setup_tests(void)
 #ifndef OPENSSL_NO_TLS1_3
     ADD_ALL_TESTS(test_set_ciphersuite, 10);
     ADD_TEST(test_ciphersuite_change);
+    ADD_ALL_TESTS(test_tls13_ciphersuite, 4);
 #ifdef OPENSSL_NO_PSK
     ADD_ALL_TESTS(test_tls13_psk, 1);
 #else
@@ -5982,6 +6307,7 @@ int setup_tests(void)
 #ifndef OPENSSL_NO_TLS1_3
     ADD_ALL_TESTS(test_export_key_mat_early, 3);
     ADD_TEST(test_key_update);
+    ADD_ALL_TESTS(test_key_update_in_write, 2);
 #endif
     ADD_ALL_TESTS(test_ssl_clear, 2);
     ADD_ALL_TESTS(test_max_fragment_len_ext, OSSL_NELEM(max_fragment_len_test));
@@ -5993,7 +6319,7 @@ int setup_tests(void)
     ADD_ALL_TESTS(test_ssl_get_shared_ciphers, OSSL_NELEM(shared_ciphers_data));
     ADD_ALL_TESTS(test_ticket_callbacks, 12);
     ADD_ALL_TESTS(test_shutdown, 7);
-    ADD_ALL_TESTS(test_cert_cb, 3);
+    ADD_ALL_TESTS(test_cert_cb, 6);
     ADD_ALL_TESTS(test_client_cert_cb, 2);
     ADD_ALL_TESTS(test_ca_names, 3);
     return 1;
@@ -6001,5 +6327,8 @@ int setup_tests(void)
 
 void cleanup_tests(void)
 {
+    OPENSSL_free(cert);
+    OPENSSL_free(privkey);
     bio_s_mempacket_test_free();
+    bio_s_always_retry_free();
 }
index 05139be..456afdf 100644 (file)
@@ -62,9 +62,11 @@ static int tls_dump_puts(BIO *bp, const char *str);
 /* Choose a sufficiently large type likely to be unused for this custom BIO */
 #define BIO_TYPE_TLS_DUMP_FILTER  (0x80 | BIO_TYPE_FILTER)
 #define BIO_TYPE_MEMPACKET_TEST    0x81
+#define BIO_TYPE_ALWAYS_RETRY      0x82
 
 static BIO_METHOD *method_tls_dump = NULL;
 static BIO_METHOD *meth_mem = NULL;
+static BIO_METHOD *meth_always_retry = NULL;
 
 /* Note: Not thread safe! */
 const BIO_METHOD *bio_f_tls_dump_filter(void)
@@ -612,6 +614,100 @@ static int mempacket_test_puts(BIO *bio, const char *str)
     return mempacket_test_write(bio, str, strlen(str));
 }
 
+static int always_retry_new(BIO *bi);
+static int always_retry_free(BIO *a);
+static int always_retry_read(BIO *b, char *out, int outl);
+static int always_retry_write(BIO *b, const char *in, int inl);
+static long always_retry_ctrl(BIO *b, int cmd, long num, void *ptr);
+static int always_retry_gets(BIO *bp, char *buf, int size);
+static int always_retry_puts(BIO *bp, const char *str);
+
+const BIO_METHOD *bio_s_always_retry(void)
+{
+    if (meth_always_retry == NULL) {
+        if (!TEST_ptr(meth_always_retry = BIO_meth_new(BIO_TYPE_ALWAYS_RETRY,
+                                                       "Always Retry"))
+            || !TEST_true(BIO_meth_set_write(meth_always_retry,
+                                             always_retry_write))
+            || !TEST_true(BIO_meth_set_read(meth_always_retry,
+                                            always_retry_read))
+            || !TEST_true(BIO_meth_set_puts(meth_always_retry,
+                                            always_retry_puts))
+            || !TEST_true(BIO_meth_set_gets(meth_always_retry,
+                                            always_retry_gets))
+            || !TEST_true(BIO_meth_set_ctrl(meth_always_retry,
+                                            always_retry_ctrl))
+            || !TEST_true(BIO_meth_set_create(meth_always_retry,
+                                              always_retry_new))
+            || !TEST_true(BIO_meth_set_destroy(meth_always_retry,
+                                               always_retry_free)))
+            return NULL;
+    }
+    return meth_always_retry;
+}
+
+void bio_s_always_retry_free(void)
+{
+    BIO_meth_free(meth_always_retry);
+}
+
+static int always_retry_new(BIO *bio)
+{
+    BIO_set_init(bio, 1);
+    return 1;
+}
+
+static int always_retry_free(BIO *bio)
+{
+    BIO_set_data(bio, NULL);
+    BIO_set_init(bio, 0);
+    return 1;
+}
+
+static int always_retry_read(BIO *bio, char *out, int outl)
+{
+    BIO_set_retry_read(bio);
+    return -1;
+}
+
+static int always_retry_write(BIO *bio, const char *in, int inl)
+{
+    BIO_set_retry_write(bio);
+    return -1;
+}
+
+static long always_retry_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+
+    switch (cmd) {
+    case BIO_CTRL_FLUSH:
+        BIO_set_retry_write(bio);
+        /* fall through */
+    case BIO_CTRL_EOF:
+    case BIO_CTRL_RESET:
+    case BIO_CTRL_DUP:
+    case BIO_CTRL_PUSH:
+    case BIO_CTRL_POP:
+    default:
+        ret = 0;
+        break;
+    }
+    return ret;
+}
+
+static int always_retry_gets(BIO *bio, char *buf, int size)
+{
+    BIO_set_retry_read(bio);
+    return -1;
+}
+
+static int always_retry_puts(BIO *bio, const char *str)
+{
+    BIO_set_retry_write(bio);
+    return -1;
+}
+
 int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
                         int min_proto_version, int max_proto_version,
                         SSL_CTX **sctx, SSL_CTX **cctx, char *certfile,
@@ -824,7 +920,7 @@ int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
     /*
      * We attempt to read some data on the client side which we expect to fail.
      * This will ensure we have received the NewSessionTicket in TLSv1.3 where
-     * appropriate. We do this twice because there are 2 NewSesionTickets.
+     * appropriate. We do this twice because there are 2 NewSessionTickets.
      */
     for (i = 0; i < 2; i++) {
         if (SSL_read_ex(clientssl, &buf, sizeof(buf), &readbytes) > 0) {
index fa19e7d..56e323f 100644 (file)
@@ -30,6 +30,9 @@ void bio_f_tls_dump_filter_free(void);
 const BIO_METHOD *bio_s_mempacket_test(void);
 void bio_s_mempacket_test_free(void);
 
+const BIO_METHOD *bio_s_always_retry(void);
+void bio_s_always_retry_free(void);
+
 /* Packet types - value 0 is reserved */
 #define INJECT_PACKET                   1
 #define INJECT_PACKET_IGNORE_REC_SEQ    2
index 6391905..2a610d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2014-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -454,4 +454,15 @@ void test_clearstanza(STANZA *s);
  */
 char *glue_strings(const char *list[], size_t *out_len);
 
+/*
+ * Pseudo random number generator of low quality but having repeatability
+ * across platforms.  The two calls are replacements for random(3) and
+ * srandom(3).
+ */
+uint32_t test_random(void);
+void test_random_seed(uint32_t sd);
+
+/* Create a file path from a directory and a filename */
+char *test_mk_file_path(const char *dir, const char *file);
+
 #endif                          /* HEADER_TESTUTIL_H */
index 6e9914c..670f5b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -112,7 +112,7 @@ void setup_test_framework()
             seed = (int)time(NULL);
         test_printf_stdout("%*s# RAND SEED %d\n", subtest_level(), "", seed);
         test_flush_stdout();
-        srand(seed);
+        test_random_seed(seed);
     }
 
 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
@@ -190,7 +190,7 @@ int run_tests(const char *test_prog_name)
         permute[i] = i;
     if (seed != 0)
         for (i = num_tests - 1; i >= 1; i--) {
-            j = rand() % (1 + i);
+            j = test_random() % (1 + i);
             ii = permute[j];
             permute[j] = permute[i];
             permute[i] = ii;
@@ -228,7 +228,7 @@ int run_tests(const char *test_prog_name)
                 jstep = 1;
             else
                 do
-                    jstep = rand() % all_tests[i].num;
+                    jstep = test_random() % all_tests[i].num;
                 while (jstep == 0 || gcd(all_tests[i].num, jstep) != 1);
 
             for (jj = 0; jj < all_tests[i].num; jj++) {
@@ -297,3 +297,21 @@ char *glue_strings(const char *list[], size_t *out_len)
     return ret;
 }
 
+char *test_mk_file_path(const char *dir, const char *file)
+{
+# ifndef OPENSSL_SYS_VMS
+    const char *sep = "/";
+# else
+    const char *sep = "";
+# endif
+    size_t len = strlen(dir) + strlen(sep) + strlen(file) + 1;
+    char *full_file = OPENSSL_zalloc(len);
+
+    if (full_file != NULL) {
+        OPENSSL_strlcpy(full_file, dir, len);
+        OPENSSL_strlcat(full_file, sep, len);
+        OPENSSL_strlcat(full_file, file, len);
+    }
+
+    return full_file;
+}
diff --git a/test/testutil/random.c b/test/testutil/random.c
new file mode 100644 (file)
index 0000000..45d0bb5
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "../testutil.h"
+
+/*
+ * This is an implementation of the algorithm used by the GNU C library's
+ * random(3) pseudorandom number generator as described:
+ *      https://www.mscs.dal.ca/~selinger/random/
+ */
+static uint32_t test_random_state[31];
+
+uint32_t test_random(void) {
+    static unsigned int pos = 3;
+
+    if (pos == 31)
+        pos = 0;
+    test_random_state[pos] += test_random_state[(pos + 28) % 31];
+    return test_random_state[pos++] / 2;
+}
+
+void test_random_seed(uint32_t sd) {
+    int i;
+    int32_t s;
+    const unsigned int mod = (1u << 31) - 1;
+
+    test_random_state[0] = sd;
+    for (i = 1; i < 31; i++) {
+        s = (int32_t)test_random_state[i - 1];
+        test_random_state[i] = (uint32_t)((16807 * (int64_t)s) % mod);
+    }
+    for (i = 34; i < 344; i++)
+        test_random();
+}
index f04ee14..9368b1c 100644 (file)
@@ -27,7 +27,7 @@
 #define KEYLEN  16
 
 /*
- * Based on the test vectors availble in:
+ * Based on the test vectors available in:
  * https://tools.ietf.org/html/draft-ietf-tls-tls13-vectors-06
  */
 
index 7340782..699887a 100755 (executable)
@@ -137,17 +137,17 @@ sub name_synopsis()
     }
 }
 
-# Check if SECTION is located before BEFORE
+# Check if SECTION ($3) is located before BEFORE ($4)
 sub check_section_location()
 {
-    my $filename = shift;
+    my $id = shift;
     my $contents = shift;
     my $section = shift;
     my $before = shift;
 
-    return unless $contents =~ /=head1 $section/
-        and $contents =~ /=head1 $before/;
-    print "$filename: $section should be placed before $before section\n"
+    return
+        unless $contents =~ /=head1 $section/ and $contents =~ /=head1 $before/;
+    print "$id $section should be placed before $before section\n"
         if $contents =~ /=head1 $before.*=head1 $section/ms;
 }
 
@@ -164,15 +164,15 @@ sub check()
         close POD;
     }
 
-    # Check if EXAMPLES is located after RETURN VALUES section.
-    &check_section_location($filename, $contents, "RETURN VALUES", "EXAMPLES") if $filename =~ m|man3/|;
-    # Check if HISTORY is located after SEE ALSO
-    &check_section_location($filename, $contents, "SEE ALSO", "HISTORY") if $filename =~ m|man3/|;
-    # Check if SEE ALSO is located after EXAMPLES
-    &check_section_location($filename, $contents, "EXAMPLES", "SEE ALSO") if $filename =~ m|man3/|;
-
     my $id = "${filename}:1:";
 
+    # Check ordering of some sections in man3
+    if ( $filename =~ m|man3/| ) {
+        &check_section_location($id, $contents, "RETURN VALUES", "EXAMPLES");
+        &check_section_location($id, $contents, "SEE ALSO", "HISTORY");
+        &check_section_location($id, $contents, "EXAMPLES", "SEE ALSO");
+    }
+
     &name_synopsis($id, $filename, $contents)
         unless $contents =~ /=for comment generic/
             or $filename =~ m@man[157]/@;
@@ -183,6 +183,10 @@ sub check()
         if $contents !~ /=cut\n$/;
     print "$id more than one cut line.\n"
         if $contents =~ /=cut.*=cut/ms;
+    print "$id EXAMPLE not EXAMPLES section.\n"
+        if $contents =~ /=head1 EXAMPLE[^S]/;
+    print "$id WARNING not WARNINGS section.\n"
+        if $contents =~ /=head1 WARNING[^S]/;
     print "$id missing copyright\n"
         if $contents !~ /Copyright .* The OpenSSL Project Authors/;
     print "$id copyright not last\n"
index 474f9f9..bf8b803 100644 (file)
@@ -4580,3 +4580,5 @@ EVP_PKEY_meth_get_digest_custom         4533      1_1_1   EXIST::FUNCTION:
 OPENSSL_INIT_set_config_filename        4534   1_1_1b  EXIST::FUNCTION:STDIO
 OPENSSL_INIT_set_config_file_flags      4535   1_1_1b  EXIST::FUNCTION:STDIO
 EVP_PKEY_get0_engine                    4536   1_1_1c  EXIST::FUNCTION:ENGINE
+X509_get0_authority_serial              4537   1_1_1d  EXIST::FUNCTION:
+X509_get0_authority_issuer              4538   1_1_1d  EXIST::FUNCTION:
index bcbb475..3ac7982 100755 (executable)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -360,7 +360,7 @@ sub do_defs
 
                # params: symbol, alias, platforms, kind
                # The reason to put this subroutine in a variable is that
-               # it will otherwise create it's own, unshared, version of
+               # it will otherwise create its own, unshared, version of
                # %tag and %variant...
                my $make_variant = sub
                {
index 0ea0296..df085fb 100755 (executable)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -417,9 +417,7 @@ print STDERR "\n" if $debug;
 &phase("Writing files");
 my $newstate = 0;
 foreach my $lib ( keys %errorfile ) {
-    if ( ! $fnew{$lib} && ! $rnew{$lib} ) {
-        next unless $rebuild;
-    }
+    next if ! $fnew{$lib} && ! $rnew{$lib} && ! $rebuild;
     next if scalar keys %modules > 0 && !$modules{$lib};
     next if $nowrite;
     print STDERR "$lib: $fnew{$lib} new functions\n" if $fnew{$lib};
@@ -455,6 +453,8 @@ foreach my $lib ( keys %errorfile ) {
 #ifndef HEADER_${lib}ERR_H
 # define HEADER_${lib}ERR_H
 
+# include <openssl/symhacks.h>
+
 EOF
     if ( $internal ) {
         # Declare the load function because the generate C file
index 9564b26..49fb88f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -65,6 +65,7 @@ use File::Spec::Functions qw/file_name_is_absolute curdir canonpath splitdir
                              rel2abs/;
 use File::Path 2.00 qw/rmtree mkpath/;
 use File::Basename;
+use Cwd qw/abs_path/;
 
 my $level = 0;
 
@@ -164,13 +165,13 @@ C<indir> takes some additional options OPTS that affect the subdirectory:
 
 =item B<create =E<gt> 0|1>
 
-When set to 1 (or any value that perl preceives as true), the subdirectory
+When set to 1 (or any value that perl perceives as true), the subdirectory
 will be created if it doesn't already exist.  This happens before BLOCK
 is executed.
 
 =item B<cleanup =E<gt> 0|1>
 
-When set to 1 (or any value that perl preceives as true), the subdirectory
+When set to 1 (or any value that perl perceives as true), the subdirectory
 will be cleaned out and removed.  This happens both before and after BLOCK
 is executed.
 
@@ -869,8 +870,8 @@ failures will result in a C<BAIL_OUT> at the end of its run.
 sub __env {
     (my $recipe_datadir = basename($0)) =~ s/\.t$/_data/i;
 
-    $directories{SRCTOP}  = $ENV{SRCTOP} || $ENV{TOP};
-    $directories{BLDTOP}  = $ENV{BLDTOP} || $ENV{TOP};
+    $directories{SRCTOP}  = abs_path($ENV{SRCTOP} || $ENV{TOP});
+    $directories{BLDTOP}  = abs_path($ENV{BLDTOP} || $ENV{TOP});
     $directories{BLDAPPS} = $ENV{BIN_D}  || __bldtop_dir("apps");
     $directories{SRCAPPS} =                 __srctop_dir("apps");
     $directories{BLDFUZZ} =                 __bldtop_dir("fuzz");
diff --git a/util/perl/TLSProxy/CertificateRequest.pm b/util/perl/TLSProxy/CertificateRequest.pm
new file mode 100644 (file)
index 0000000..bc41053
--- /dev/null
@@ -0,0 +1,105 @@
+# Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+
+package TLSProxy::CertificateRequest;
+
+use vars '@ISA';
+push @ISA, 'TLSProxy::Message';
+
+sub new
+{
+    my $class = shift;
+    my ($server,
+        $data,
+        $records,
+        $startoffset,
+        $message_frag_lens) = @_;
+
+    my $self = $class->SUPER::new(
+        $server,
+        TLSProxy::Message::MT_CERTIFICATE_REQUEST,
+        $data,
+        $records,
+        $startoffset,
+        $message_frag_lens);
+
+    $self->{extension_data} = "";
+
+    return $self;
+}
+
+sub parse
+{
+    my $self = shift;
+    my $ptr = 1;
+
+    if (TLSProxy::Proxy->is_tls13()) {
+        my $request_ctx_len = unpack('C', $self->data);
+        my $request_ctx = substr($self->data, $ptr, $request_ctx_len);
+        $ptr += $request_ctx_len;
+
+        my $extensions_len = unpack('n', substr($self->data, $ptr));
+        $ptr += 2;
+        my $extension_data = substr($self->data, $ptr);
+        if (length($extension_data) != $extensions_len) {
+            die "Invalid extension length\n";
+        }
+        my %extensions = ();
+        while (length($extension_data) >= 4) {
+            my ($type, $size) = unpack("nn", $extension_data);
+            my $extdata = substr($extension_data, 4, $size);
+            $extension_data = substr($extension_data, 4 + $size);
+            $extensions{$type} = $extdata;
+        }
+        $self->extension_data(\%extensions);
+
+        print "    Extensions Len:".$extensions_len."\n";
+    }
+    # else parse TLSv1.2 version - we don't support that at the moment
+}
+
+#Reconstruct the on-the-wire message data following changes
+sub set_message_contents
+{
+    my $self = shift;
+    my $data;
+    my $extensions = "";
+
+    foreach my $key (keys %{$self->extension_data}) {
+        my $extdata = ${$self->extension_data}{$key};
+        $extensions .= pack("n", $key);
+        $extensions .= pack("n", length($extdata));
+        $extensions .= $extdata;
+    }
+
+    $data = pack('n', length($extensions));
+    $data .= $extensions;
+    $self->data($data);
+}
+
+#Read/write accessors
+sub extension_data
+{
+    my $self = shift;
+    if (@_) {
+        $self->{extension_data} = shift;
+    }
+    return $self->{extension_data};
+}
+sub set_extension
+{
+    my ($self, $ext_type, $ext_data) = @_;
+    $self->{extension_data}{$ext_type} = $ext_data;
+}
+sub delete_extension
+{
+    my ($self, $ext_type) = @_;
+    delete $self->{extension_data}{$ext_type};
+}
+1;
index 5682ae3..10b6156 100644 (file)
@@ -129,6 +129,11 @@ use constant {
     CIPHER_TLS13_AES_256_GCM_SHA384 => 0x1302
 };
 
+use constant {
+    CLIENT => 0,
+    SERVER => 1
+};
+
 my $payload = "";
 my $messlen = -1;
 my $mt;
@@ -338,6 +343,15 @@ sub create_message
             [@message_frag_lens]
         );
         $message->parse();
+    } elsif ($mt == MT_CERTIFICATE_REQUEST) {
+        $message = TLSProxy::CertificateRequest->new(
+            $server,
+            $data,
+            [@message_rec_list],
+            $startoffset,
+            [@message_frag_lens]
+        );
+        $message->parse();
     } elsif ($mt == MT_CERTIFICATE_VERIFY) {
         $message = TLSProxy::CertificateVerify->new(
             $server,
index f7bca02..71acaff 100644 (file)
@@ -19,6 +19,7 @@ use TLSProxy::ClientHello;
 use TLSProxy::ServerHello;
 use TLSProxy::EncryptedExtensions;
 use TLSProxy::Certificate;
+use TLSProxy::CertificateRequest;
 use TLSProxy::CertificateVerify;
 use TLSProxy::ServerKeyExchange;
 use TLSProxy::NewSessionTicket;
index c53b96d..04441b5 100644 (file)
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -116,7 +116,8 @@ sub checkhandshake($$$$)
                     && $message->mt() != TLSProxy::Message::MT_SERVER_HELLO
                     && $message->mt() !=
                        TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS
-                    && $message->mt() != TLSProxy::Message::MT_CERTIFICATE);
+                    && $message->mt() != TLSProxy::Message::MT_CERTIFICATE
+                    && $message->mt() != TLSProxy::Message::MT_CERTIFICATE_REQUEST);
 
             next if $message->mt() == TLSProxy::Message::MT_CERTIFICATE
                     && !TLSProxy::Proxy::is_tls13();
@@ -124,7 +125,7 @@ sub checkhandshake($$$$)
             my $extchnum = 1;
             my $extshnum = 1;
             for (my $extloop = 0;
-                    $extensions[$extloop][2] != 0;
+                    $extensions[$extloop][3] != 0;
                     $extloop++) {
                 $extchnum = 2 if $extensions[$extloop][0] != TLSProxy::Message::MT_CLIENT_HELLO
                                  && TLSProxy::Proxy::is_tls13();
@@ -135,6 +136,7 @@ sub checkhandshake($$$$)
                 next if $extensions[$extloop][0] == TLSProxy::Message::MT_SERVER_HELLO
                                  && $extshnum != $shnum;
                 next if ($message->mt() != $extensions[$extloop][0]);
+                next if ($message->server() != $extensions[$extloop][2]);
                 $numtests++;
             }
             $numtests++;
@@ -182,7 +184,8 @@ sub checkhandshake($$$$)
                     && $message->mt() != TLSProxy::Message::MT_SERVER_HELLO
                     && $message->mt() !=
                        TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS
-                    && $message->mt() != TLSProxy::Message::MT_CERTIFICATE);
+                    && $message->mt() != TLSProxy::Message::MT_CERTIFICATE
+                    && $message->mt() != TLSProxy::Message::MT_CERTIFICATE_REQUEST);
 
             next if $message->mt() == TLSProxy::Message::MT_CERTIFICATE
                     && !TLSProxy::Proxy::is_tls13();
@@ -197,7 +200,7 @@ sub checkhandshake($$$$)
             my $msgexts = $message->extension_data();
             my $extchnum = 1;
             my $extshnum = 1;
-            for (my $extloop = 0, $extcount = 0; $extensions[$extloop][2] != 0;
+            for (my $extloop = 0, $extcount = 0; $extensions[$extloop][3] != 0;
                                 $extloop++) {
                 #In TLSv1.3 we can have two ClientHellos if there has been a
                 #HelloRetryRequest, and they may have different extensions. Skip
@@ -211,12 +214,13 @@ sub checkhandshake($$$$)
                 next if $extensions[$extloop][0] == TLSProxy::Message::MT_SERVER_HELLO
                                  && $extshnum != $shnum;
                 next if ($message->mt() != $extensions[$extloop][0]);
-                ok (($extensions[$extloop][2] & $exttype) == 0
+                next if ($message->server() != $extensions[$extloop][2]);
+                ok (($extensions[$extloop][3] & $exttype) == 0
                       || defined ($msgexts->{$extensions[$extloop][1]}),
                     "Extension presence check (Message: ".$message->mt()
-                    ." Extension: ".($extensions[$extloop][2] & $exttype).", "
+                    ." Extension: ".($extensions[$extloop][3] & $exttype).", "
                     .$extloop.")");
-                $extcount++ if (($extensions[$extloop][2] & $exttype) != 0);
+                $extcount++ if (($extensions[$extloop][3] & $exttype) != 0);
             }
             ok($extcount == keys %$msgexts, "Extensions count mismatch ("
                                             .$extcount.", ".(keys %$msgexts)